TestCase
В простых тестах утверждения могут идти одно за другим. Иногда, однако, выгодно обернуть утверждения в тестовый класс и тем самым их структурировать.
Класс должен наследоваться от Tester\TestCase, и мы называем его
просто TestCase. Класс должен содержать тестовые методы, имена которых
начинаются на test. Эти методы будут выполнены как тесты:
use Tester\Assert;
class RectangleTest extends Tester\TestCase
{
public function testOne()
{
Assert::same(/* ... */);
}
public function testTwo()
{
Assert::match(/* ... */);
}
}
# Запускаем тестовые методы
(new RectangleTest)->run();
Записанный так TestCase можно ещё дополнить методами setUp() и
tearDown(). Они вызываются соответственно перед каждым тестовым
методом и после него:
use Tester\Assert;
class NextTest extends Tester\TestCase
{
protected function setUp()
{
# Подготовка
}
protected function tearDown()
{
# Уборка
}
public function testOne()
{
Assert::same(/* ... */);
}
public function testTwo()
{
Assert::match(/* ... */);
}
}
# Запускаем тестовые методы
(new NextTest)->run();
/*
Порядок вызова методов
----------------------
setUp()
testOne()
tearDown()
setUp()
testTwo()
tearDown()
*/
Если ошибка возникнет на этапе setUp() или tearDown(), тест в
целом провалится. Если ошибка возникнет в самом тестовом методе, метод
tearDown() всё равно будет выполнен, но ошибки внутри него
подавляются.
Внутри тестового метода вы можете в любой момент пропустить текущий
тест вызовом $this->skip('причина'), например когда не выполнено
предварительное условие.
Мы рекомендуем в начале файла теста написать аннотацию @testCase. Запускатель тестов из командной строки тогда будет выполнять отдельные методы TestCase в разных процессах и параллельно в нескольких потоках. Это может существенно ускорить весь процесс тестирования.
<?php
/** @testCase */
Аннотации методов
Для тестовых методов доступно несколько аннотаций, облегчающих тестирование. Записывайте их над тестовым методом.
@throws
Это равносильно использованию Assert::exception() внутри тестового
метода, но запись понятнее:
/**
* @throws RuntimeException
*/
public function testOne()
{
// ...
}
/**
* @throws LogicException Неверный порядок аргументов
*/
public function testTwo()
{
// ...
}
@dataProvider
Эта аннотация полезна, когда вы хотите запустить тестовый метод несколько раз с разными параметрами. (Не путайте её с одноимённой аннотацией для файлов тестов.)
После неё укажите имя метода, который возвращает аргументы для тестового метода. Этот метод должен вернуть массив или объект Traversable. Простой пример:
public function getLoopArgs()
{
return [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
];
}
/**
* @dataProvider getLoopArgs
*/
public function testLoop($a, $b, $c)
{
// ...
}
Вторая разновидность аннотации @dataProvider принимает параметром
путь к INI-файлу (относительно файла теста). Метод вызывается столько
раз, сколько секций в INI-файле. Файл loop-args.ini:
[one]
a=1
b=2
c=3
[two]
a=4
b=5
c=6
[three]
a=7
b=8
c=9
и метод, который использует INI-файл:
/**
* @dataProvider loop-args.ini
*/
public function testLoop($a, $b, $c)
{
// ...
}
Точно так же вместо INI-файла можно сослаться на PHP-скрипт. Он должен
вернуть массив или объект Traversable. Файл loop-args.php:
return [
['a' => 1, 'b' => 2, 'c' => 3],
['a' => 4, 'b' => 5, 'c' => 6],
['a' => 7, 'b' => 8, 'c' => 9],
];
Как и у провайдера данных для файлов тестов, после имени файла можно дописать фильтрующий запрос, чтобы метод выполнялся только для подходящих секций.