テストのアノテーション

アノテーションは、コマンドラインのテストの実行器がテストをどう扱うかを決めます。テストのファイルの先頭に書きます。

アノテーションは大文字と小文字を区別しません。また、テストをふつうの PHP のスクリプトとして手で走らせたときには働きません。

例です。

/**
 * TEST: Basic database query test.
 *
 * @dataProvider files/databases.ini
 * @exitCode 56
 * @phpVersion < 8.4
 */

require __DIR__ . '/../bootstrap.php';

TEST

これは実のところアノテーションではありません。テストの題名を指定するだけで、落ちたときやログに表示されます。

@skip

テストが飛ばされます。テストを一時的に止めておくのに役立ちます。

@phpVersion

対応する PHP のバージョンで走っていなければ、テストは飛ばされます。アノテーションは @phpVersion [演算子] バージョン と書きます。演算子は省略でき、既定は >= です。例です。

/**
 * @phpVersion 8.1
 * @phpVersion < 8.4
 * @phpVersion != 8.2.5
 */

@phpExtension

指定した PHP の拡張がすべて読み込まれていなければ、テストは飛ばされます。ひとつのアノテーションに複数の拡張を並べても、アノテーションを何度も使ってもかまいません。

/**
 * @phpExtension pdo, pdo_pgsql, pdo_mysql
 * @phpExtension json
 */

@dataProvider

このアノテーションは、テストのファイルを違う入力データで何度も走らせたいときに役立ちます。(TestCaseの同じ名前のアノテーションと混同しないでください。)

@dataProvider file.ini と書きます。ファイルのパスはテストのファイルからの相対です。テストは INI ファイルの区画の数だけ走ります。databases.ini という INI ファイルがあるとしましょう。

[mysql]
dsn = "mysql:host=127.0.0.1"
user = root
password = ******

[postgresql]
dsn = "pgsql:host=127.0.0.1;dbname=test"
user = postgres
password = ******

[sqlite]
dsn = "sqlite::memory:"

そして同じディレクトリに database.phpt のファイルがあります。

/**
 * @dataProvider databases.ini
 */

$args = Tester\Environment::loadData();

テストは 3 回走り、$args にはそれぞれ mysqlpostgresqlsqlite の区画の値が入ります。

もうひとつの書き方として、アノテーションに疑問符を付けられます。@dataProvider? file.ini です。この場合、INI ファイルが存在しなければテストは飛ばされます。

このアノテーションの力はこれで終わりではありません。INI ファイルの名前のうしろに、その区画についてテストを走らせるかどうかを決める条件を書けます。INI ファイルを広げてみましょう。

[mysql]
dsn = "mysql:host=127.0.0.1"
user = root
password = ******

[postgresql 8.4]
dsn = "pgsql:host=127.0.0.1;dbname=test"
user = postgres
password = ******

[postgresql 9.1]
dsn = "pgsql:host=127.0.0.1;dbname=test;port=5433"
user = postgres
password = ******

[sqlite]
dsn = "sqlite::memory:"

そして条件付きのアノテーションを使います。

/**
 * @dataProvider  databases.ini  postgresql, >=9.0
 */

テストは postgresql 9.1 の区画について 1 回だけ走ります。ほかの区画は条件の絞り込みを満たしません。

同じように、INI ファイルの代わりに PHP のスクリプトを指せます。それは配列か Traversable のオブジェクトを返さなければなりません。databases.php のファイルです。

return [
	'postgresql 8.4' => [
		'dsn' => '...',
		'user' => '...',
	],

	'postgresql 9.1' => [
		'dsn' => '...',
		'user' => '...',
	],
];

@multiple

@multiple N と書きます。N は整数です。テストはちょうど N 回走ります。

@testCase

このアノテーションにパラメータはありません。テストを TestCaseのクラスとして書くときに使います。この場合、コマンドラインのテストの実行器は個々のメソッドを別々のプロセスで、複数のスレッドを使って並行して実行します。おかげでテスト全体がかなり速くなります。

@exitCode

@exitCode N と書きます。N はテストの期待される終了コードです。たとえばテストの中で exit(10) を呼ぶなら、アノテーションは @exitCode 10 と書きます。テストが違うコードで終わると、落ちたと見なされます。アノテーションを省くと、終了コード 0(ゼロ)が確かめられます。

@httpCode

このアノテーションは PHP の実行ファイルが CGI の場合にだけ働き、そうでなければ無視されます。@httpCode NNN と書きます。NNN は期待される HTTP のコードです。アノテーションを省くと、HTTP のコード 200 が確かめられます。NNN をゼロと評価される文字列(たとえば any)として書くと、HTTP のコードは確かめられません。

@outputMatch と @outputMatchFile

これらのアノテーションの働きは Assert::match()Assert::matchFile() のアサーションと同じです。ただし形は、テストが標準出力へ送った文の中で探されます。テストが致命的なエラーで終わることを期待していて、その出力を確かめる必要があるときに役立ちます。

@phpIni

テストのために INI の設定の値を指定します。たとえば @phpIni precision=20 と書きます。コマンドラインから -d precision=20 のパラメータで値を指定したのと同じように働きます。