TestCase

В простых тестах утверждения могут следовать одно за другим. Но иногда полезно заключить утверждения в тестовый класс и структурировать их таким образом.

Класс должен быть потомком Tester\TestCase, и мы говорим о нем просто как о testcase.

use Tester\Assert;

class RectangleTest extends Tester\TestCase
{
	public function testOne()
	{
		Assert::same(/* ... */);
	}

	public function testTwo()
	{
		Assert::match(/* ... */);
	}
}

# Run testing methods
(new RectangleTest)->run();

Мы можем обогатить тесткейс методами setUp() и tearDown(). Они вызываются до/после каждого метода тестирования:

use Tester\Assert;

class NextTest extends Tester\TestCase
{
	public function setUp()
	{
		# Preparation
	}

	public function tearDown()
	{
		# Clean-up
	}

	public function testOne()
	{
		Assert::same(/* ... */);
	}

	public function testTwo()
	{
		Assert::match(/* ... */);
	}
}

# Run testing methods
(new NextTest)->run();

/*


Method Calls Order
------------------
setUp()
testOne()
tearDown()

setUp()
testTwo()
tearDown()
*/

Если ошибка произойдет в фазе setUp() или tearDown(), тест будет провален. Если ошибка возникает в методе тестирования, то метод tearDown() вызывается в любом случае, но с подавленными в нем ошибками.

Мы рекомендуем писать аннотацию @testCase в начале теста, тогда программа запуска тестов командной строки будет запускать отдельные методы тесткейса в отдельных процессах и параллельно в нескольких потоках. Это может значительно ускорить весь процесс тестирования.

<?php
/** @testCase */

Аннотирование методов

Существует несколько аннотаций, которые помогут нам в тестировании методов. Мы пишем их в направлении метода тестирования.

@throws

Это такое же использование Assert::exception() внутри метода тестирования. Но обозначение более читабельно:

/**
 * @throws RuntimeException
 */
public function testOne()
{
	// ...
}


/**
 * @throws LogicException  Wrong argument order
 */
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)
{
	// ...
}

Аналогично, мы можем передать путь к PHP-скрипту вместо INI. Он должен возвращать массив или Traversable. Файл loop-args.php:

return [
	['a' => 1, 'b' => 2, 'c' => 3],
	['a' => 4, 'b' => 5, 'c' => 6],
	['a' => 7, 'b' => 8, 'c' => 9],
];