スキップしてメイン コンテンツに移動

[PHP]そろそろ真面目に自動テストしよう

PHPで自動テストを行うための、PHPUnitを実戦投入するためのセットアップ方法を書き並べます。
慣れれば一番手っ取り早い(と思っている)PHPUnitを使ってみます。



まず必要なのは、PEAR。これがないとダメ。
ubuntuならapt-getでインストールできます。既にインストールされている場合は次へ行きましょう。
sudo apt-get install php-pear

無事インストールが終わったら、まずはPEARのアップグレードをかけてみましょう。リポジトリのバージョンは最新ではないというのはいつものことです。
sudo pear upgrade --force PEAR

PEARのアップグレードはPEARコマンドで行います。rubygemやnpmと同じですね!

それでは、PHPUnitをインストールします。
pear config-set auto_discover 1
pear install pear.phpunit.de/PHPUnit

1行目はおまじないみたいなものです。無事にインストールできれば、とりあえず使える状態です。

がしかし、アナタ、1からテストコードを書くつもりですか? 恐ろしい・・・。おぞましい発想ですよ、それは!
世の中には、既に書いたコードからテストクラスのひな形を書き起こしてくれる便利なジェネレーターがあるんですからッ!
それがPHPUnit_SkeletonGeneratorです(まんまな名前)。
pear install phpunit/PHPUnit_SkeletonGenerator

これだけ用意しておけば、とりあえずは大丈夫でしょう! PHPUnitのオプションパッケージには、まだまだ便利なパッケージがあるようなので、いいのがあれば教えて下さい。

では、テストしてみましょう!
テスト対象のファイルは以下のものを使用します。
<?php
class test1{
 var $fuga;
 var $fugafuga;

 function setFuga($a){
  $this->fuga = $a;
 }
 
 function setFugafuga($b){
  $this->fugafuga = $b;
 }
 
 function fugafugafuga(){
  echo $this->fuga + $this->fugafuga;
 }
}

上のソースをtest1.phpというファイル名で保存します。PHPUnitを利用した自動テストではファイル名のネーミングも結構重要になってきますのでファイル名とその中に保存するクラスの名前は一緒にしたほうがいいです。
ex::)
class test1 → test1.php
class hogehoge → hogehoge.php

そして、phpunit-skelgenで自動出力したひな形のファイル名はそれぞれ以下のようになっています。
ex::)
test1.php → test1Test.php
hogehoge.php → hogehogeTest.php

それではテストケースのひな形を一気に作ります。
phpunit-skelgen --test test1

これだけでひな形は完成です。できたひな形はこんな感じです。
<?php
/**
 * Generated by PHPUnit_SkeletonGenerator on 2012-01-26 at 18:07:24.
 */
class test1Test extends PHPUnit_Framework_TestCase
{
    /**
     * @var test1
     */
    protected $object;

    /**
     * Sets up the fixture, for example, opens a network connection.
     * This method is called before a test is executed.
     */
    protected function setUp()
    {
        $this->object = new test1;
    }

    /**
     * Tears down the fixture, for example, closes a network connection.
     * This method is called after a test is executed.
     */
    protected function tearDown()
    {
    }

    /**
     * @covers test1::setFuga
     * @todo   Implement testSetFuga().
     */
    public function testSetFuga()
    {
        // Remove the following lines when you implement this test.
        $this->markTestIncomplete(
          'This test has not been implemented yet.'
        );
    }

    /**
     * @covers test1::setFugafuga
     * @todo   Implement testSetFugafuga().
     */
    public function testSetFugafuga()
    {
        // Remove the following lines when you implement this test.
        $this->markTestIncomplete(
          'This test has not been implemented yet.'
        );
    }

    /**
     * @covers test1::fugafugafuga
     * @todo   Implement testFugafugafuga().
     */
    public function testFugafugafuga()
    {
        // Remove the following lines when you implement this test.
        $this->markTestIncomplete(
          'This test has not been implemented yet.'
        );
    }
}

なんとなくうまくいっているようなので、一度テストを実行してみます。
phpunit test1  #コマンド入力
PHPUnit 3.6.9 by Sebastian Bergmann.



Time: 0 seconds, Memory: 2.25Mb

OK (0 tests, 0 assertions)

OKと出ました。良い感じです。しかし肝心のテスト内容は0。アサーションも0です。
まぁ何せひな形ですからね・・・。

2012/01/30 追記
phpunitで走らせてるソースが違うというコメントをいただきましたのでチェックしましたが、上の例ではテストしたいソースの方をテストにかけている状態なので、そりゃテスト0だわという話でした。

本来は
phpunit test1Test

でした。
ただ、これでも今回自動生成したひな形ではエラーが出るので、test1.phpをincludeするか、18行目の「$this->object = new test1;」をコメントアウトするかしないとダメなようです。なんでだろう? 元のクラスを利用する場面もあるので事前に準備してるだけかなぁ。また優しい人のコメントをお待ちしております! ありがとうございました!

2012/04/03 追記
元ファイルをincludeして、「$this->object」を利用してテスト対象クラスを呼び出すのがphpunit-skelgenのやり方みたいです。


以下は自分の備忘録のようなものですが、ファイル名とクラス名に一貫性を持たせられない事も往々にしてあるでしょう。
そういう時にもPHPUnitは対応できます。

phpunit-skelgen --test -- [クラス名] [ファイル名]

これで、[クラス名]+Test.phpというテストケースのひな形を生成することができます。
ただ、この方法で作ったテストケースは、ファイル名、クラス名、テストケースのファイル名に一貫性が無いので、テストケースの先頭でテスト対象のファイルをインクルードする必要があります(他の解決法がわかりませんでした)

2012/04/03 追記
テスト対象のファイルを常にincludeするのが良いようです。

デバッグコードを書くくらいなら、テストコードを書けという言葉があるくらい、劇的にバグ混入が減るPHPUnitを是非使ってみてください!


see also:
php-mcryptがyumでインストールできないときに幸せになる方法
PHPerが一瞬でC言語をマスターする方法
PHPのmysql系関数のまとめ
さくらインターネットの .mailfilter にハマる


コメント

  1. $ phpunit test1
    でテストされないのは
    $ phpunit test1.php
    と指定されたのと同じだからです。

    $ phpunit test1Test
    と入力すれば以下のようになるはずです。


    PHPUnit 3.6.9 by Sebastian Bergmann.

    III

    Time: 0 seconds, Memory: 3.00Mb

    OK, but incomplete or skipped tests!
    Tests: 3, Assertions: 0, Incomplete: 3.

    返信削除
    返信
    1. こちらでも確認しましたが
      phpunit test1Test でした!

      そうした場合に今回のテストケースで発生する問題についても触れた内容をエントリに追加しました。

      中途半端な検証でエントリを出してしまって申し訳ないです。

      ご指摘ありがとうございました。

      削除

コメントを投稿

このブログの人気の投稿

[VB.NET]オレオレ証明書でSSL通信するための短絡的な解決法

VB.NETソフトウェアでサーバーと通信することはよくある事だと思いますが、最近はHTTPを使って明けっ広げに刺しに行くよりHTTPSを使って暗号化してこそこそやった方が時代の流れに即した感じですよね(違うか)。 いちいちテスト環境でSSL証明書を用意するのも面倒だということで、セキュリティ的には全くよろしくない方法で迂回できるので紹介します。

[JS]Canvasでよく使う描画テクまとめ

HTMLで画像をいじくりたい時は、canvasを利用して編集するのは一般的ですが、WindowsストアアプリではHTML+CSS+JSでのアプリ開発ができる事もあって、簡単な画像編集であれば、C#やVBを使うより分かりやすいし資料が多く、C++でDirectXをガリガリ書くよりお手軽。入出力もファイルピッカーを使えば簡単に実装できます。今回は、Windowsのコードではなく、Canvasを利用する時のJavaScriptを使いどきに合わせてまとめていきます。

curl の基本的な使い方 -設定編-

今回のcurl TIPSは、curlをより日常的に使っていくためのHow toです。curlには、数多くのオプションが用意されていて、それらを組み合わせる事で様々な事が楽になるでしょう。サービス監視の自動化などにはまさにcurlの得意分野です。 今回は、curlを更に自分のものにしていくために大事なカスタマイズの部分を解説します。