TestCase
W prostych testach asercje mogą następować jedna po drugiej. Czasem jednak korzystnie jest opakować asercje w klasę testową i tym samym je ustrukturyzować.
Klasa musi rozszerzać Tester\TestCase, a nazywamy ją po prostu TestCase. Klasa musi zawierać metody
testowe zaczynające się od test. Te metody zostaną wykonane 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 TestCase można jeszcze wzbogacić o metody setUp() i tearDown(). Wywoływane są
odpowiednio przed każdą metodą testową i po niej:
use Tester\Assert;
class NextTest extends Tester\TestCase
{
protected function setUp()
{
# Przygotowanie
}
protected 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 w fazie setUp() albo tearDown() dojdzie do błędu, test jako całość nie przejdzie. Jeśli
błąd wystąpi w samej metodzie testowej, metoda tearDown() mimo to zostanie wykonana, ale ewentualne błędy w niej
są tłumione.
Wewnątrz metody testowej możesz w dowolnym momencie pominąć bieżący test, wywołując
$this->skip('powód'), na przykład gdy warunek wstępny nie jest spełniony.
Zalecamy zapisanie na początku pliku testu adnotacji @testCase. Runner testów z wiersza poleceń będzie wtedy wykonywał poszczególne metody TestCase w osobnych procesach i równolegle w wielu wątkach. Może to znacząco przyspieszyć cały proces testowania.
<?php
/** @testCase */
Adnotacje metod
Dla metod testowych dostępnych jest kilka adnotacji ułatwiających testowanie. Zapisujemy je nad metodą testową.
@throws
Jest odpowiednikiem użycia Assert::exception() wewnątrz metody testowej, ale zapis jest przejrzystszy:
/**
* @throws RuntimeException
*/
public function testOne()
{
// ...
}
/**
* @throws LogicException Wrong argument order
*/
public function testTwo()
{
// ...
}
@dataProvider
Ta adnotacja przydaje się, gdy chcesz uruchomić metodę testową wielokrotnie z różnymi parametrami. (Nie myl jej z adnotacją o tej samej nazwie dla plików testów.)
Za nią podaj nazwę metody zwracającej argumenty dla metody testowej. Metoda ta musi zwrócić tablicę albo obiekt 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)
{
// ...
}
Drugi wariant adnotacji @dataProvider przyjmuje jako parametr ścieżkę do pliku INI (względem pliku testu). Metoda
wywoływana jest tyle razy, ile sekcji ma plik INI. 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 używająca pliku INI:
/**
* @dataProvider loop-args.ini
*/
public function testLoop($a, $b, $c)
{
// ...
}
Podobnie zamiast pliku INI możesz odwołać się do skryptu PHP. Musi on zwrócić tablicę albo obiekt Traversable. Plik
loop-args.php:
return [
['a' => 1, 'b' => 2, 'c' => 3],
['a' => 4, 'b' => 5, 'c' => 6],
['a' => 7, 'b' => 8, 'c' => 9],
];
Podobnie jak przy data providerze dla plików testów możesz za nazwą pliku dopisać zapytanie filtrujące, żeby uruchomić metodę tylko dla pasujących sekcji.