TestCase

În testele simple, aserțiunile pot urma una după alta. Uneori, însă, este mai avantajos să împachetăm aserțiunile într-o clasă de test și astfel să le structurăm.

Clasa trebuie să fie descendentă a Tester\TestCase și, simplificat, vorbim despre ea ca despre un testcase. Clasa trebuie să conțină metode de testare care încep cu test. Aceste metode vor fi rulate ca teste:

use Tester\Assert;

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

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

# Rularea metodelor de testare
(new RectangleTest)->run();

Un test scris astfel poate fi îmbogățit ulterior cu metodele setUp() și tearDown(). Acestea sunt apelate înainte, respectiv după fiecare metodă de testare:

use Tester\Assert;

class NextTest extends Tester\TestCase
{
	public function setUp()
	{
		# Pregătire
	}

	public function tearDown()
	{
		# Curățenie
	}

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

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

# Rularea metodelor de testare
(new NextTest)->run();

/*


Ordinea apelării metodelor
--------------------------
setUp()
testOne()
tearDown()

setUp()
testTwo()
tearDown()
*/

Dacă apare o eroare în faza setUp() sau tearDown(), testul eșuează în totalitate. Dacă apare o eroare în metoda de testare, chiar și așa metoda tearDown() se va rula, însă cu suprimarea erorilor din ea.

Recomandăm să scrieți la începutul testului adnotarea @testCase, atunci rulatorul de teste din linia de comandă va rula metodele individuale ale testcase-ului în procese separate și în paralel în mai multe fire de execuție. Acest lucru poate accelera semnificativ întregul proces de testare.

<?php
/** @testCase */

Adnotări ale metodelor

Pentru metodele de testare avem la dispoziție câteva adnotări care ne facilitează testarea. Le scriem lângă metoda de testare.

@throws

Este echivalentul utilizării Assert::exception() în interiorul metodei de testare. Notația este însă mai lizibilă:

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


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

@dataProvider

Dacă dorim să rulăm metoda de testare de mai multe ori, dar cu parametri diferiți, această adnotare este potrivită. (Nu confundați cu adnotarea omonimă pentru fișiere.)

După ea specificăm numele metodei care returnează argumentele pentru metoda de testare. Metoda trebuie să returneze un array sau Traversable. Un exemplu simplu:

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


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

A doua variantă a adnotării @dataProvider acceptă ca parametru calea către un fișier INI (relativă la fișierul cu testul). Metoda este apelată de atâtea ori câte secțiuni sunt în fișierul INI. Fișierul 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 care utilizează fișierul INI:

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

În mod similar, în loc de fișierul INI putem face referire la un script PHP. Acesta trebuie să returneze un array sau Traversable. Fișierul loop-args.php:

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