Nette Documentation Preview

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

.[perex]
Анотациите определят как ще се третират тестовете от [стартера на тестове от командния ред|running-tests]. Записват се в началото на файла с теста.

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

Пример:

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

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


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


@skip .[filter]
---------------
Тестът се пропуска. Полезно е за временно изключване на тестове.


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

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


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

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


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

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

```php
/**
 * @dataProvider databases.ini
 */

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

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

Съществува още вариант, при който анотацията записваме с въпросителен знак като `@dataProvider? file.ini`. В този случай тестът се пропуска, ако 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:"
```

и ще използваме анотация с условие:

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

Тестът ще бъде стартиран само веднъж и то за секцията `postgresql 9.1`. Останалите секции не преминават през филтъра на условието.

Подобно можем вместо INI файл да препратим към PHP скрипт. Той трябва да върне масив или Traversable. Файл `databases.php`:

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

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


@multiple .[filter]
-------------------
Записваме като `@multiple N`, където `N` е цяло число. Тестът ще бъде стартиран точно N пъти.


@testCase .[filter]
-------------------
Анотацията няма параметри. Използваме я, ако тестовете пишем като [TestCase | TestCase] класове. В този случай стартерът на тестове от командния ред ще стартира отделните методи в самостоятелни процеси и паралелно в няколко нишки. Това може значително да ускори целия процес на тестване.


@exitCode .[filter]
-------------------
Записваме като `@exitCode N`, където `N` е кодът на връщане на стартирания тест. Ако в теста например се извиква `exit(10)`, анотацията записваме като `@exitCode 10` и ако тестът завърши с друг код, това се счита за провал. Ако анотацията не се посочи, се проверява код на връщане 0 (нула).


@httpCode .[filter]
-------------------
Анотацията се прилага само ако PHP бинарният файл е CGI. Иначе се игнорира. Записваме като `@httpCode NNN`, където `NNN` е очакваният HTTP код. Ако анотацията не се посочи, се проверява HTTP код 200. Ако `NNN` запишем като низ, оценен на нула, например `any`, HTTP кодът не се проверява.


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


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

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

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

При анотациите не се взема предвид размерът на буквите. Също така нямат никакво влияние, ако тестът се стартира ръчно като обикновен 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.