Prev Next

付録B アノテーション

アノテーションとはメタデータを表す特別な構文のことで、 プログラミング言語のソースコードに追加することができます。 PHP そのものにはソースコードにアノテーションする専用の仕組みはありませんが、 ドキュメンテーションブロックに @アノテーション名 引数 のようなタグを書くことでアノテーションを表すという記法が PHP コミュニティ内で一般に使われています。 PHP では、リフレクション API の getDocComment() メソッドを使えば関数、クラス、メソッド、属性 それぞれのドキュメンテーションブロックにアクセスすることができます。 PHPUnit などのアプリケーションでは、 この情報をもとに実行時の振る舞いを設定するのです。

本章では、PHPUnit がサポートするすべてのアノテーションについて解説します。

@author

@author アノテーションは @group アノテーション (@group を参照ください) のエイリアスで、 テストの作者にもとづいたフィルタリングができるようになります。

@backupGlobals

グローバル変数の保存や復元を、テストケースクラスのすべてのテストで完全に無効にすることができます。 このように使います。

/**
 * @backupGlobals disabled
 */
class MyTest extends PHPUnit_Framework_TestCase
{
    // ...
}

@backupGlobals アノテーションは、テストメソッドレベルで使うこともできます。 これによって、保存と復元の操作をより細やかに制御できるようになります。

/**
 * @backupGlobals disabled
 */
class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @backupGlobals enabled
     */
    public function testThatInteractsWithGlobalVariables()
    {
        // ...
    }
}

@backupStaticAttributes

クラスの静的属性の保存や復元を、テストケースクラスのすべてのテストで完全に無効にすることができます。 このように使います。

/**
 * @backupStaticAttributes disabled
 */
class MyTest extends PHPUnit_Framework_TestCase
{
    // ...
}

@backupStaticAttributes アノテーションは、テストメソッドレベルで使うこともできます。 これによって、保存と復元の操作をより細やかに制御できるようになります。

/**
 * @backupStaticAttributes disabled
 */
class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @backupStaticAttributes enabled
     */
    public function testThatInteractsWithStaticAttributes()
    {
        // ...
    }
}

@codeCoverageIgnore*

@codeCoverageIgnore@codeCoverageIgnoreStart、そして @codeCoverageIgnoreEnd アノテーションを使うと、 コード内の特定の行をカバレッジ解析の対象外にできます。

利用法は 「コードブロックの無視」 を参照ください。

@covers

@covers アノテーションをテストコードで使うと、 そのテストメソッドがどのメソッドをテストするのかを指定することができます。

/**
 * @covers BankAccount::getBalance
 */
public function testBalanceIsInitiallyZero()
{
    $this->assertEquals(0, $this->ba->getBalance());
}

これを指定した場合は、指定したメソッドのみのコードカバレッジ情報を考慮することになります。

表 B.1@covers アノテーションの構文を示します。

表B.1 カバーするメソッドを指定するためのアノテーション

アノテーション 説明
@covers ClassName::methodName そのテストメソッドが指定したメソッドをカバーすることを表します。
@covers ClassName そのテストメソッドが指定したクラスのすべてのメソッドをカバーすることを表します。
@covers ClassName<extended> そのテストメソッドが、指定したクラスとその親クラスおよびインターフェイスのすべてのメソッドをカバーすることを表します。
@covers ClassName::<public> そのテストメソッドが、指定したクラスのすべての public メソッドをカバーすることを表します。
@covers ClassName::<protected> そのテストメソッドが、指定したクラスのすべての protected メソッドをカバーすることを表します。
@covers ClassName::<private> そのテストメソッドが、指定したクラスのすべての private メソッドをカバーすることを表します。
@covers ClassName::<!public> そのテストメソッドが、指定したクラスのすべての非 public メソッドをカバーすることを表します。
@covers ClassName::<!protected> そのテストメソッドが、指定したクラスのすべての非 protected メソッドをカバーすることを表します。
@covers ClassName::<!private> そのテストメソッドが、指定したクラスのすべての非 private メソッドをカバーすることを表します。
@covers ::functionName そのテストメソッドが、指定したグローバル関数をカバーすることを表します。

@coversNothing

@coversNothing アノテーションをテストコードで使うと、 そのテストケースについてはコードカバレッジ情報を記録しないように指定できます。

これはインテグレーションテストで使えます。例として 例 14.3 を参照ください。

このメソッドはクラスレベルおよびメソッドレベルで使え、 あらゆる @covers タグを上書きします。

@dataProvider

テストメソッドには任意の引数を渡すことができます。 引数は、データプロバイダメソッド (例 4.4provider()) から渡されます。 使用するデータプロバイダメソッドを指定するには @dataProvider アノテーションを使います。

詳細は 「データプロバイダ」 を参照ください。

@depends

PHPUnit は、テストメソッド間の依存性の明示的な宣言をサポートしています。 この依存性とは、テストメソッドが実行される順序を定義するものではありません。 プロデューサーがテストフィクスチャを作ってそのインスタンスを返し、 依存するコンシューマーがそれを受け取って利用するというものです。 例 4.2 は、@depends アノテーションを使ってテストメソッドの依存性をあらわす例です。

詳細は 「テストの依存性」 を参照ください。

@expectedException

例 4.7 は、テストするコード内で例外がスローされたかどうかを @expectedException アノテーションを使用して調べる方法を示すものです。

詳細は 「例外のテスト」 を参照ください。

@expectedExceptionCode

@expectedExceptionCode アノテーションを @expectedException と組み合わせて使うと、 スローされた例外のエラーコードについてのアサーションが可能となり、 例外をより狭い範囲に特定できるようになります。

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @expectedException     MyException
     * @expectedExceptionCode 20
     */
    public function testExceptionHasErrorcode20()
    {
        throw new MyException('Some Message', 20);
    }
}

テストを実行しやすくし、重複を減らすために、 ショートカットを使ってクラス定数を指定することができます。 @expectedExceptionCode で "@expectedExceptionCode ClassName::CONST" のようにして使います。

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
      * @expectedException     MyException
      * @expectedExceptionCode MyClass::ERRORCODE
      */
    public function testExceptionHasErrorcode20()
    {
      throw new MyException('Some Message', 20);
    }
}
class MyClass
{
    const ERRORCODE = 20;
}

@expectedExceptionMessage

@expectedExceptionMessage アノテーションは @expectedExceptionCode と似ており、 例外のエラーメッセージに関するアサーションを行います。

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @expectedException        MyException
     * @expectedExceptionMessage Some Message
     */
    public function testExceptionHasRightMessage()
    {
        throw new MyException('Some Message', 20);
    }
}

期待するメッセージを、例外メッセージの一部にすることもできます。 これは、特定の名前や渡したパラメータが例外に表示されることを確かめたいけれども 例外メッセージ全体は固定していない場合に便利です。

class MyTest extends PHPUnit_Framework_TestCase
{
     /**
      * @expectedException        MyException
      * @expectedExceptionMessage broken
      */
     public function testExceptionHasRightMessage()
     {
         $param = "broken";
         throw new MyException('Invalid parameter "'.$param.'".', 20);
     }
}

テストを実行しやすくし、重複を減らすために、 ショートカットを使ってクラス定数を指定することができます。 @expectedExceptionMessage で "@expectedExceptionMessage ClassName::CONST" のようにして使います。 サンプルコードは @expectedExceptionCode を参照ください。

@group

あるテストを、ひとつあるいは複数のグループに属するものとすることができます。 @group アノテーションをこのように使用します。

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @group specification
     */
    public function testSomething()
    {
    }

    /**
     * @group regresssion
     * @group bug2204
     */
    public function testSomethingElse()
    {
    }
}

特定のグループに属するテストのみを選んで実行するには、 コマンドラインのテストランナーの場合は --group スイッチあるいは --exclude-group スイッチを指定します。XML 設定ファイルの場合は、 それぞれ対応するディレクティブを指定します。

@outputBuffering

@outputBuffering アノテーションを使うと、PHP の 出力バッファリング をこのように制御することができます。

/**
 * @outputBuffering enabled
 */
class MyTest extends PHPUnit_Framework_TestCase
{
    // ...
}

@outputBuffering アノテーションは、テストメソッドレベルで使うこともできます。 これによって、出力バッファリングをより細やかに制御できるようになります。

/**
 * @outputBuffering disabled
 */
class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @outputBuffering enabled
     */
    public function testThatPrintsSomething()
    {
        // ...
    }
}

@preserveGlobalState

テストを別プロセスで実行するときに、 PHPUnit は親プロセスのグローバルな状態を保存しようと試みます。 親プロセスのすべてのグローバル状態をシリアライズし、 子プロセス内で最後にそれをアンシリアライズするのです。 しかし、親プロセスのグローバル状態の中にもしシリアライズできないものがあれば、 問題が発生します。この問題に対応するために、グローバル状態の保存を無効にすることができます。 そのために使うのが @preserveGlobalState アノテーションです。

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @runInSeparateProcess
     * @preserveGlobalState disabled
     */
    public function testInSeparateProcess()
    {
        // ...
    }
}

@requires

@requires アノテーションを使うと、共通の事前条件 (たとえば PHP のバージョンや拡張モジュールのインストール状況) を満たさないときにテストをスキップできます。

条件に指定できる内容やその例については 表 9.3 を参照ください。

@runTestsInSeparateProcesses

テストクラス内のすべてのテストケースを、個別の PHP プロセスで実行するように指示します。

/**
 * @runTestsInSeparateProcesses
 */
class MyTest extends PHPUnit_Framework_TestCase
{
    // ...
}

注意: デフォルトで、PHPUnit は親プロセスのグローバルな状態を保存しようと試みます。 親プロセスのすべてのグローバル状態をシリアライズし、 子プロセス内で最後にそれをアンシリアライズするのです。 しかし、親プロセスのグローバル状態の中にもしシリアライズできないものがあれば、 問題が発生します。この問題に対応するために、グローバル状態の保存を無効にすることができます。 この問題の対処法については @preserveGlobalState を参照ください。

@runInSeparateProcess

そのテストを個別の PHP プロセスで実行するように指示します。

class MyTest extends PHPUnit_Framework_TestCase
{
    /**
     * @runInSeparateProcess
     */
    public function testInSeparateProcess()
    {
        // ...
    }
}

注意: デフォルトで、PHPUnit は親プロセスのグローバルな状態を保存しようと試みます。 親プロセスのすべてのグローバル状態をシリアライズし、 子プロセス内で最後にそれをアンシリアライズするのです。 しかし、親プロセスのグローバル状態の中にもしシリアライズできないものがあれば、 問題が発生します。この問題に対応するために、グローバル状態の保存を無効にすることができます。 この問題の対処法については @preserveGlobalState を参照ください。

@test

テストメソッド名の先頭に test をつけるかわりに、メソッドのドキュメンテーションブロックで @test アノテーションを使ってそのメソッドがテストメソッドであることを指定することができます。

/**
 * @test
 */
public function initialBalanceShouldBe0()
{
    $this->assertEquals(0, $this->ba->getBalance());
}

@testdox


            

@ticket


            
Prev Next
1. 自動テスト
2. PHPUnit の目標
3. PHPUnit のインストール
PEAR
Composer
PHP Archive (PHAR)
オプションのパッケージ
アップグレード
4. PHPUnit 用のテストの書き方
テストの依存性
データプロバイダ
例外のテスト
PHP のエラーのテスト
出力内容のテスト
アサーション
assertArrayHasKey()
assertClassHasAttribute()
assertClassHasStaticAttribute()
assertContains()
assertContainsOnly()
assertContainsOnlyInstancesOf()
assertCount()
assertEmpty()
assertEqualXMLStructure()
assertEquals()
assertFalse()
assertFileEquals()
assertFileExists()
assertGreaterThan()
assertGreaterThanOrEqual()
assertInstanceOf()
assertInternalType()
assertJsonFileEqualsJsonFile()
assertJsonStringEqualsJsonFile()
assertJsonStringEqualsJsonString()
assertLessThan()
assertLessThanOrEqual()
assertNull()
assertObjectHasAttribute()
assertRegExp()
assertStringMatchesFormat()
assertStringMatchesFormatFile()
assertSame()
assertSelectCount()
assertSelectEquals()
assertSelectRegExp()
assertStringEndsWith()
assertStringEqualsFile()
assertStringStartsWith()
assertTag()
assertThat()
assertTrue()
assertXmlFileEqualsXmlFile()
assertXmlStringEqualsXmlFile()
assertXmlStringEqualsXmlString()
5. コマンドラインのテストランナー
Command-Line switches
6. フィクスチャ
tearDown() よりも setUp()
バリエーション
フィクスチャの共有
グローバルな状態
7. テストの構成
ファイルシステムを用いたテストスイートの構成
XML 設定ファイルを用いたテストスイートの構成
8. データベースのテスト
データベースのテストに対応しているベンダー
データベースのテストの難しさ
データベーステストの四段階
1. データベースのクリーンアップ
2. フィクスチャの準備
3–5. テストの実行、結果の検証、そして後始末
PHPUnit のデータベーステストケースの設定
getConnection() の実装
getDataSet() の実装
データベーススキーマ (DDL) とは?
ヒント: 自前でのデータベーステストケースの抽象化
データセットとデータテーブルについて知る
利用できる実装
外部キーには注意
自作のデータセットやデータテーブルの実装
接続 API
データベースアサーション API
テーブルの行数のアサーション
テーブルの状態のアサーション
クエリの結果のアサーション
複数のテーブルの状態のアサーション
よくある質問
PHPUnit は、テストごとにデータベーススキーマを作り直すの?
PDO を使ったアプリケーションじゃないと Database Extension を使えないの?
Too much Connections というエラーが出たらどうすればいい?
フラット XML や CSV のデータセットで NULL を扱う方法は?
9. 不完全なテスト・テストの省略
不完全なテスト
テストの省略
@requires によるテストのスキップ
10. テストダブル
スタブ
モックオブジェクト
ウェブサービスのスタブおよびモック
ファイルシステムのモック
11. テストの進め方
開発中のテスト
デバッグ中のテスト
12. テスト駆動開発
銀行口座の例
13. 振舞駆動開発
ボウリングゲームの例
14. コードカバレッジ解析
カバーするメソッドの指定
コードブロックの無視
ファイルのインクルードや除外
エッジケース
15. テストのその他の使用法
アジャイルな文書作成
複数チームでのテスト
16. 雛形ジェネレータ
テストケースクラスの雛形の作成
テストケースクラスからのクラスの雛形の作成
17. PHPUnit と Selenium
Selenium Server
インストール
PHPUnit_Extensions_Selenium2TestCase
PHPUnit_Extensions_SeleniumTestCase
18. ログ出力
テスト結果 (XML)
テスト結果 (TAP)
テスト結果 (JSON)
コードカバレッジ (XML)
コードカバレッジ (テキスト)
19. PHPUnit の拡張
PHPUnit_Framework_TestCase のサブクラスの作成
カスタムアサーションの作成
PHPUnit_Framework_TestListener の実装
PHPUnit_Extensions_TestDecorator のサブクラスの作成
PHPUnit_Framework_Test の実装
A. アサーション
B. アノテーション
@author
@backupGlobals
@backupStaticAttributes
@codeCoverageIgnore*
@covers
@coversNothing
@dataProvider
@depends
@expectedException
@expectedExceptionCode
@expectedExceptionMessage
@group
@outputBuffering
@preserveGlobalState
@requires
@runTestsInSeparateProcesses
@runInSeparateProcess
@test
@testdox
@ticket
C. XML 設定ファイル
PHPUnit
テストスイート
グループ
コードカバレッジ対象のファイルの追加や除外
ログ出力
テストリスナー
PHP INI 項目や定数、グローバル変数の設定
Selenium RC の設定ブラウザ
D. 目次
E. 参考文献
F. 著作権