TestCase

W prostych testach asercje mogą następować jedna po drugiej. Czasami jednak wygodniej jest asercje opakować w klasę testową i w ten sposób je ustrukturyzować.

Klasa musi być potomkiem Tester\TestCase i w uproszczeniu nazywamy ją testcase. Klasa musi zawierać metody testowe zaczynające się na test. Te metody będą uruchamiane jako testy:

use Tester\Assert;

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

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

# Uruchomienie metod testowych
(new RectangleTest)->run();

Tak napisany test można dalej wzbogacić o metody setUp() i tearDown(). Są wywoływane przed, resp. za każdą metodą testową:

use Tester\Assert;

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

	public function tearDown()
	{
		# Sprzątanie
	}

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

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

# Uruchomienie metod testowych
(new NextTest)->run();

/*


Kolejność wywoływania metod
---------------------------
setUp()
testOne()
tearDown()

setUp()
testTwo()
tearDown()
*/

Jeśli dojdzie do błędu w fazie setUp() lub tearDown(), test ogólnie zawiedzie. Jeśli dojdzie do błędu w metodzie testowej, mimo to metoda tearDown() zostanie uruchomiona, jednak z pominięciem błędów w niej.

Zalecamy na początek testu napisać adnotację @testCase, wtedy narzędzie do uruchamiania testów z wiersza poleceń będzie uruchamiać poszczególne metody testcase w oddzielnych procesach i równolegle w wielu wątkach. Może to znacznie przyspieszyć cały proces testowania.

<?php
/** @testCase */

Adnotacje metod

Przy metodach testowych mamy do dyspozycji kilka adnotacji, które ułatwią nam testowanie. Zapisujemy je przy metodzie testowej.

@throws

Jest ekwiwalentem użycia Assert::exception() wewnątrz metody testowej. Zapis jest jednak bardziej przejrzysty:

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


/**
 * @throws LogicException  Wrong argument order
 */
public function testTwo()
{
	// ...
}

@dataProvider

Jeśli chcemy metodę testową uruchomić wielokrotnie, ale z innymi parametrami, przyda się właśnie ta adnotacja. (Nie mylić z adnotacją o tej samej nazwie dla plików.)

Za nią podamy nazwę metody, która zwraca argumenty dla metody testowej. Metoda musi zwrócić tablicę lub Traversable. Prosty przykład:

public function getLoopArgs()
{
	return [
		[1, 2, 3],
		[4, 5, 6],
		[7, 8, 9],
	];
}


/**
 * @dataProvider getLoopArgs
 */
public function testLoop($a, $b, $c)
{
	// ...
}

Druga warianta adnotacji @dataProvider przyjmuje jako parametr ścieżkę do pliku INI (relatywnie do pliku z testem). Metoda jest wywoływana tyle razy, ile jest w pliku INI sekcji. Plik loop-args.ini:

[one]
a=1
b=2
c=3

[two]
a=4
b=5
c=6

[three]
a=7
b=8
c=9

i metoda, która wykorzystuje plik INI:

/**
 * @dataProvider loop-args.ini
 */
public function testLoop($a, $b, $c)
{
	// ...
}

Podobnie możemy zamiast pliku INI odwołać się do skryptu PHP. Musi on zwrócić tablicę lub Traversable. Plik loop-args.php:

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