アサーションの使い方

2010年4月14日(水)
伊丹 久兼

アノテーションの利用(1)

 ここまで、アサーションの使い方について見てきました。ただし、アサーションだけでは、いくらひな型を自動生成できるといっても、テスト・メソッドの中身は自分で書くことになるので、やはり手間は掛かってしまいます。

ここで、アノテーションが生きます。値の一致/不一致や大小の比較など、基本的なテストだけであれば、@assertアノテーションをテスト対象のプログラムのコメントに埋め込むことで、テスト・ケースのひな型を生成する時に、テスト・メソッドの実装まで自動的に行ってくれます。

例えば、FizzBuzzクラスのevaluate()メソッドのテストを、アノテーションを使って行う場合を考えてみます。メソッドの仕様は図2のソース・コードに書かれたコメントの通りなのですが、コメント行の下に「@assert (3) == 'Fizz'」という行がある点に注意してください。このように書くことで、evaluate(3)としてメソッドが呼ばれた場合には、'Fizz'という文字列を返す。という意味になります。

						<?php

class FizzBuzz
{
    /**
     * 3の倍数のときに'Fizz'、
     * 5の倍数のときに'Buzz'、
     * 15の倍数のときに'FizzBuzz'を返す
     *
     * @assert (3) == 'Fizz'
     * @assert (5) == 'Buzz'

     * @assert (15) == 'FizzBuzz'
     */
    public function evaluate($n)
    {  
        $ret = '';
        if (($n % 3) == 0) $ret = 'Fizz';
        if (($n % 5) == 0) $ret .= 'Buzz';
        return $ret;
    }
}
?>

					
図2:FizzBuzz.php

アノテーションの利用(2)

 さらに、アノテーションを使うと、テスト・ケースのひな型を作成しなくても、直接プログラム本体を PHPUnitで実行することができます。

アノテーションで記述されたテストが実行され、結果が表示されます。
--------------------------------------------------------------------------------
  $ phpunit FizzBuzz
  PHPUnit 3.4.12 by Sebastian Bergmann.

  ...

  Time: 0 seconds, Memory: 5.75Mb

  OK (3 tests, 3 assertions)
--------------------------------------------------------------------------------

もちろん、ひな型を生成することもできます。どのようなテスト・ケースが自動生成されるのか確認してみましょう。

phpunitコマンドを実行してひな型を生成します。
--------------------------------------------------------------------------------
  $ phpunit --skeleton-test FizzBuzz
--------------------------------------------------------------------------------

生成されたテスト・ケースをテキスト・エディタで開くと、@assertアノテーションの各行とテスト・メソッドが1対1になっていることが分かりま す。
--------------------------------------------------------------------------------
  /**
   * Generated from @assert (3) == 'Fizz'.
   */
  public function testEvaluate()
  {
    $this->assertEquals(
      'Fizz',
      $this->object->evaluate(3)
    );
  }

  /**
   * Generated from @assert (5) == 'Buzz'.
   */
  public function testEvaluate2()
  {
    $this->assertEquals(
      'Buzz',
      $this->object->evaluate(5)
    );
  }

  /**
   * Generated from @assert (15) == 'FizzBuzz'.
   */
  public function testEvaluate3()
  {
    $this->assertEquals(
      'FizzBuzz',
      $this->object->evaluate(15)
    );
  }
--------------------------------------------------------------------------------

このように、@assertアノテーションを使えば、基本的なテストを自動的に生成できます。ただし、生成されたテスト・ケースを見てみると、 @assertの数だけテスト・メソッドが作成されてしまっています。テスト対象のプログラムの可読性を考えても、使用は必要最小限にとどめるべきでしょ う。

より多くのデータについてテストを確認したい場合には、次に説明するデータ・プロバイダを利用します。

PCIアイオス株式会社

テンアートニ(現サイオステクノロジー)、ゼンド・ジャパンなどを経て現在、PCIアイオスに勤務。これまでに組込み開発からWebシステム開発まで幅広く開発を経験。現在は、オープンソースソフトウェアを利用したシステムの開発、運用、パフォーマンスチューニングを担当。特にLAMP(Linux/Apache/MySQL/PHP)環境を得意とする。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています