TestCase

Em testes simples, as asserções podem seguir uma após a outra. No entanto, às vezes é mais vantajoso agrupar as asserções em uma classe de teste e, assim, estruturá-las.

A classe deve ser descendente de Tester\TestCase e, simplificadamente, nos referimos a ela como testcase. A classe deve conter métodos de teste que começam com test. Esses métodos serão executados como testes:

use Tester\Assert;

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

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

# Execução dos métodos de teste
(new RectangleTest)->run();

Um teste escrito desta forma pode ser enriquecido com os métodos setUp() e tearDown(). Eles são chamados antes e depois de cada método de teste, respectivamente:

use Tester\Assert;

class NextTest extends Tester\TestCase
{
	public function setUp()
	{
		# Preparação
	}

	public function tearDown()
	{
		# Limpeza
	}

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

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

# Execução dos métodos de teste
(new NextTest)->run();

/*


Ordem de chamada dos métodos
----------------------------
setUp()
testOne()
tearDown()

setUp()
testTwo()
tearDown()
*/

Se ocorrer um erro na fase setUp() ou tearDown(), o teste falha no geral. Se ocorrer um erro no método de teste, mesmo assim o método tearDown() será executado, mas com a supressão de erros nele.

Recomendamos escrever a anotação @testCase no início do teste, então o executor de testes da linha de comando executará os métodos individuais do testcase em processos separados e em paralelo em múltiplas threads. Isso pode acelerar significativamente todo o processo de teste.

<?php
/** @testCase */

Anotações de Métodos

Para os métodos de teste, temos disponíveis várias anotações que facilitam os testes. Escrevemo-las junto ao método de teste.

@throws

É equivalente ao uso de Assert::exception() dentro do método de teste. A notação, no entanto, é mais clara:

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


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

@dataProvider

Se quisermos executar o método de teste várias vezes, mas com parâmetros diferentes, esta anotação é útil. (Não confunda com a anotação de mesmo nome para arquivos.)

Após ela, indicamos o nome do método que retorna os argumentos para o método de teste. O método deve retornar um array ou Traversable. Um exemplo simples:

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


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

A segunda variante da anotação @dataProvider aceita como parâmetro o caminho para um arquivo INI (relativo ao arquivo de teste). O método é chamado tantas vezes quantas seções houver no arquivo INI. Arquivo loop-args.ini:

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

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

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

e o método que utiliza o arquivo INI:

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

Da mesma forma, em vez de um arquivo INI, podemos referenciar um script PHP. Ele deve retornar um array ou Traversable. Arquivo loop-args.php:

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