2012年12月15日土曜日

PHPのunit testをやってみる (基礎編1)

前回の内容

http://masatonave.blogspot.com/2012/12/macphpunit-test.html

今回の内容

目的

単体テストの書き方を覚える。

方法

PHP Unitのマニュアルの第4章を写経し、自分の理解を記録に残す。

テストの書き方


  1. テストはテストクラスを作って実行する。
    • テストクラスのクラス名は "テスト対象クラス名"+ "Test"
    • テストクラスはPHPUnit_Framework_TestCaseを継承して作る
  2. テスト項目1つに対して1つテストメソッドを実装する。
    • メソッドの名前はtestで始まる
    • テストメソッドはクラスメソッドで、アクセス制御はpublic
  3. テストメソッド
    • アサーションメソッドを使って、値の比較など検証を実施する。
      • 例 : assertEqual($val1, $val2);  → $val1と$val2が等しいことを検証
    • 1つのテストメソッド内ではテストしたいことだけ、検証する
  4. 実行順序など、テスト間に依存関係がある場合は@dependsアノテーションを付ける

実践

コード

PHP Unit 公式の例4.2
http://www.phpunit.de/manual/current/ja/writing-tests-for-phpunit.html

<?php
class StackTest extends PHPUnit_Framework_TestCase
{
    public function testEmpty()
    {
        $stack = array();
        $this->assertEmpty($stack);
 
        return $stack;
    }
 
    /**
     * @depends testEmpty
     */
    public function testPush(array $stack)
    {
        array_push($stack, 'foo');
        $this->assertEquals('foo', $stack[count($stack)-1]);
        $this->assertNotEmpty($stack);
 
        return $stack;
    }
 
    /**
     * @depends testPush
     */
    public function testPop(array $stack)
    {
        $this->assertEquals('foo', array_pop($stack));
        $this->assertEmpty($stack);
    }
}
?>
エディタで書いて、stack_test_case.phpとして保存。

実行結果

$ phpunit stack_test_case.php 
PHPUnit 3.7.10 by Sebastian Bergmann.

...

Time: 1 second, Memory: 4.50Mb

OK (3 tests, 5 assertions)

テストコードがやっていること

この例題は、スタックのpushとpopを検証する。

testEmpty()メソッド
スタックの生成と検証の2つの役割を持っている。空の配列を作り、assertEmptyで空であることを検証し、フィクスチャとしてその配列を返す。 フィクスチャ(fixture)とは、テストしたい状況。

testPush()メソッド
ここでテストしているのは「スタックにpushできるか」ということ。依存関係としてtestEmpty()メソッドを指定しており、testEmpty()が用意した空のスタックを受け取ってarray_push()の実行結果に対して検証している。また、要素が1つ積まれたスタックというフィクスチャを用意する役目も持っている。

testPop()メソッド
「スタックからpopできるか」を検証している。依存関係としてtestPush()メソッドを指定し、要素が1つあるスタックを受け取って、array_pop()の実行結果に対して検証している。

補足: プロデューサとコンシューマ

  • プロデューサ:テスト対象(フィクスチャ)を用意するテストメソッド。 
    • testEmpty()は空のスタックを生成するプロデューサ
    • testPush()は要素に'foo'が1つ積まれたスタックを生成するプロデューサ
  • コンシューマ:プロデューサの生成したインスタンスに依存するテストメソッド
    • testPush()はtestEmpty()に依存するコンシューマ
    • testPop()はtestPush()に依存するコンシューマ

テストを書く上で大事なこと


1つの要件が変わったときに、すべてのテストメソッドを書き直すようでは、テストが開発の負担になってしまう。

テストメソッド間の独立性をできるだけ上げること。

具体的には、フィクスチャと依存関係を上手に使い、テストする対象の生成はメソッド内に書かない。

0 件のコメント:

コメントを投稿