TestCase
В прости тестове assertion-ите могат да следват една след друга. Понякога обаче е по-удобно assertion-ите да се опаковат в тестов клас и така да се структурират.
Класът трябва да бъде наследник на 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();
Така написаният тест може да бъде допълнително обогатен с методите
setUp()
и tearDown()
. Те се извикват преди, респ. след всеки
тестов метод:
use Tester\Assert;
class NextTest extends Tester\TestCase
{
public function setUp()
{
# Подготовка
}
public function tearDown()
{
# Почистване
}
public function testOne()
{
Assert::same(/* ... */);
}
public function testTwo()
{
Assert::match(/* ... */);
}
}
# Стартиране на тестовите методи
(new NextTest)->run();
/*
Ред на извикване на методите
----------------------------
setUp()
testOne()
tearDown()
setUp()
testTwo()
tearDown()
*/
Ако възникне грешка във фазата setUp()
или tearDown()
, тестът
като цяло се проваля. Ако възникне грешка в тестовия метод, въпреки
това методът tearDown()
се стартира, но с потискане на грешките
в него.
Препоръчваме в началото на теста да напишете анотацията @testCase, тогава стартерът на тестове от командния ред ще стартира отделните методи на 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)
{
// ...
}
Подобно можем вместо 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],
];