TestCase
En las pruebas sencillas, las aserciones pueden ir una tras otra. A veces, sin embargo, resulta ventajoso envolver las aserciones en una clase de prueba para estructurarlas.
La clase debe extender Tester\TestCase y nos referimos a ella simplemente como TestCase. La clase debe
contener métodos de prueba que empiecen por test. Esos métodos se ejecutarán como pruebas:
use Tester\Assert;
class RectangleTest extends Tester\TestCase
{
public function testOne()
{
Assert::same(/* ... */);
}
public function testTwo()
{
Assert::match(/* ... */);
}
}
# Ejecuta los métodos de prueba
(new RectangleTest)->run();
Un TestCase escrito así se puede mejorar además con los métodos setUp() y tearDown(). Se llaman,
respectivamente, antes y después de cada método de prueba:
use Tester\Assert;
class NextTest extends Tester\TestCase
{
protected function setUp()
{
# Preparación
}
protected function tearDown()
{
# Limpieza
}
public function testOne()
{
Assert::same(/* ... */);
}
public function testTwo()
{
Assert::match(/* ... */);
}
}
# Ejecuta los métodos de prueba
(new NextTest)->run();
/*
Orden de las llamadas a los métodos
-----------------------------------
setUp()
testOne()
tearDown()
setUp()
testTwo()
tearDown()
*/
Si se produce un error en la fase setUp() o tearDown(), la prueba fallará en su conjunto. Si el
error se produce en el propio método de prueba, el método tearDown() se ejecuta igualmente, pero los errores que
ocurran en él se suprimen.
Dentro de un método de prueba puede omitir la prueba actual en cualquier momento llamando a
$this->skip('reason'), por ejemplo cuando no se cumple un requisito previo.
Recomendamos escribir la anotación @testCase al principio del archivo de prueba. El ejecutor de pruebas de la línea de comandos ejecutará entonces los distintos métodos del TestCase en procesos separados y en paralelo en varios hilos. Eso puede acelerar notablemente todo el proceso de pruebas.
<?php
/** @testCase */
Anotaciones de los métodos
Para los métodos de prueba hay disponibles varias anotaciones que facilitan las pruebas. Escríbalas encima del método de prueba.
@throws
Equivale a usar Assert::exception() dentro del método de prueba, pero la notación es más clara:
/**
* @throws RuntimeException
*/
public function testOne()
{
// ...
}
/**
* @throws LogicException Wrong argument order
*/
public function testTwo()
{
// ...
}
@dataProvider
Esta anotación es útil cuando quiere ejecutar el método de prueba varias veces con distintos parámetros. (No la confunda con la anotación del mismo nombre para los archivos de prueba.)
Después de ella indique el nombre de un método que devuelva los argumentos para el método de prueba. Ese método debe devolver un array o un objeto Traversable. Un ejemplo sencillo:
public function getLoopArgs()
{
return [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
];
}
/**
* @dataProvider getLoopArgs
*/
public function testLoop($a, $b, $c)
{
// ...
}
La segunda variante de la anotación @dataProvider acepta como parámetro la ruta a un archivo INI (relativa al archivo
de prueba). El método se llama tantas veces como secciones tenga el archivo INI. Archivo loop-args.ini:
[one]
a=1
b=2
c=3
[two]
a=4
b=5
c=6
[three]
a=7
b=8
c=9
y el método que usa el archivo INI:
/**
* @dataProvider loop-args.ini
*/
public function testLoop($a, $b, $c)
{
// ...
}
De forma parecida, en lugar de un archivo INI puede referirse a un script PHP. Debe devolver un array o un objeto Traversable.
Archivo loop-args.php:
return [
['a' => 1, 'b' => 2, 'c' => 3],
['a' => 4, 'b' => 5, 'c' => 6],
['a' => 7, 'b' => 8, 'c' => 9],
];
Igual que con el data provider de los archivos de prueba, tras el nombre del archivo puede añadir una consulta de filtrado para ejecutar el método solo para las secciones que encajen.