Анотации на тестове

Анотациите определят как ще се третират тестовете от стартера на тестове от командния ред. Записват се в началото на файла с теста.

При анотациите не се взема предвид размерът на буквите. Също така нямат никакво влияние, ако тестът се стартира ръчно като обикновен PHP скрипт.

Пример:

/**
 * ТЕСТ: Основен тест за заявка към база данни.
 *
 * @dataProvider files/databases.ini
 * @exitCode 56
 * @phpVersion < 5.5
 */

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

TEST

Това всъщност дори не е анотация, само определя заглавието на теста, което се изписва при провал или в лога.

@skip

Тестът се пропуска. Полезно е за временно изключване на тестове.

@phpVersion

Тестът се пропуска, ако не е стартиран със съответната версия на PHP. Анотацията записваме като @phpVersion [оператор] версия. Операторът можем да пропуснем, по подразбиране е >=. Примери:

/**
 * @phpVersion 5.3.3
 * @phpVersion < 5.5
 * @phpVersion != 5.4.5
 */

@phpExtension

Тестът се пропуска, ако не са заредени всички посочени PHP разширения. Повече разширения можем да посочим в една анотация или да я използваме многократно.

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

@dataProvider

Ако искаме тестов файл да се стартира многократно, но с различни входни данни, е полезна именно тази анотация. (Не бъркайте със същата анотация за TestCase.)

Записваме като @dataProvider file.ini, пътят до файла се взема относително спрямо файла с теста. Тестът ще бъде стартиран толкова пъти, колкото секции има в INI файла. Да предположим INI файл databases.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();

Тестът ще бъде стартиран три пъти и $args ще съдържа винаги стойности от секцията mysql, postgresql или sqlite.

Съществува още вариант, при който анотацията записваме с въпросителен знак като @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. Останалите секции не преминават през филтъра на условието.

Подобно можем вместо 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

Функцията на анотациите е идентична с assertion-ите Assert::match() и Assert::matchFile(). Шаблонът (pattern) обаче се търси в текста, който тестът е изпратил на своя стандартен изход. Приложение намира, ако предполагаме, че тестът ще завърши с фатална грешка и трябва да проверим неговия изход.

@phpIni

За теста задава конфигурационни INI стойности. Записваме например като @phpIni precision=20 и работи по същия начин, както ако бяхме задали стойността от командния ред чрез параметър -d precision=20.