TestCase

Dans les tests simples, les assertions peuvent se succéder. Parfois, cependant, il est plus avantageux d'emballer les assertions dans une classe de test et de les structurer ainsi.

La classe doit hériter de Tester\TestCase et nous en parlons simplement comme d'un testcase. La classe doit contenir des méthodes de test commençant par test. Ces méthodes seront exécutées comme des tests :

use Tester\Assert;

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

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

# Exécution des méthodes de test
(new RectangleTest)->run();

Un test écrit de cette manière peut être enrichi par les méthodes setUp() et tearDown(). Elles sont appelées avant, resp. après chaque méthode de test :

use Tester\Assert;

class NextTest extends Tester\TestCase
{
	public function setUp()
	{
		# Préparation
	}

	public function tearDown()
	{
		# Nettoyage
	}

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

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

# Exécution des méthodes de test
(new NextTest)->run();

/*


Ordre d'appel des méthodes
--------------------------
setUp()
testOne()
tearDown()

setUp()
testTwo()
tearDown()
*/

Si une erreur se produit dans la phase setUp() ou tearDown(), le test échoue globalement. Si une erreur se produit dans la méthode de test, la méthode tearDown() est quand même exécutée, mais avec suppression des erreurs qu'elle contient.

Nous recommandons d'écrire l'annotation @testCase au début du test, alors le lanceur de tests depuis la ligne de commande exécutera les méthodes individuelles du testcase dans des processus séparés et en parallèle dans plusieurs threads. Cela peut accélérer considérablement l'ensemble du processus de test.

<?php
/** @testCase */

Annotations de méthodes

Pour les méthodes de test, nous disposons de plusieurs annotations qui nous facilitent les tests. Nous les écrivons à côté de la méthode de test.

@throws

C'est l'équivalent de l'utilisation de Assert::exception() à l'intérieur de la méthode de test. L'écriture est cependant plus claire :

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


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

@dataProvider

Si nous voulons exécuter la méthode de test plusieurs fois, mais avec des paramètres différents, cette annotation est utile. (Ne pas confondre avec l'annotation du même nom pour les fichiers.)

Après elle, nous indiquons le nom de la méthode qui renvoie les arguments pour la méthode de test. La méthode doit retourner un tableau ou un Traversable. Exemple simple :

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


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

La deuxième variante de l'annotation @dataProvider accepte comme paramètre le chemin vers un fichier INI (relativement au fichier de test). La méthode est appelée autant de fois qu'il y a de sections dans le fichier INI. Fichier loop-args.ini :

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

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

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

et la méthode qui utilise le fichier INI :

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

De même, au lieu d'un fichier INI, nous pouvons faire référence à un script PHP. Celui-ci doit retourner un tableau ou un Traversable. Fichier loop-args.php :

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