TestCase

In einfachen Tests können die Assertions einzeln folgen. Manchmal ist es jedoch sinnvoll, die Aussagen in eine Testklasse einzuschließen und sie auf diese Weise zu strukturieren.

Die Klasse muss von Tester\TestCase abstammen und wir sprechen einfach von testcase.

use Tester\Assert;

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

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

# Run testing methods
(new RectangleTest)->run();

Wir können einen Testfall um die Methoden setUp() und tearDown() erweitern. Sie werden vor/nach jeder Testmethode aufgerufen:

use Tester\Assert;

class NextTest extends Tester\TestCase
{
	public function setUp()
	{
		# Preparation
	}

	public function tearDown()
	{
		# Clean-up
	}

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

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

# Run testing methods
(new NextTest)->run();

/*


Method Calls Order
------------------
setUp()
testOne()
tearDown()

setUp()
testTwo()
tearDown()
*/

Wenn in einer setUp() oder tearDown() Phase ein Fehler auftritt, wird der Test fehlschlagen. Tritt ein Fehler in der Testmethode auf, wird die Methode tearDown() trotzdem aufgerufen, allerdings mit unterdrückten Fehlern.

Wir empfehlen Ihnen, die Annotation @testCase an den Anfang des Tests zu schreiben, dann führt der Kommandozeilen-Testrunner die einzelnen Testfallmethoden in separaten Prozessen und parallel in mehreren Threads aus. Dies kann den gesamten Testprozess erheblich beschleunigen.

<?php
/** @testCase */

Annotation von Methoden

Es gibt ein paar Anmerkungen, die uns beim Testen von Methoden helfen. Wir schreiben sie in Richtung der Testmethode.

@throws

Es ist die gleiche Verwendung von Assert::exception() innerhalb einer Testmethode. Die Schreibweise ist jedoch lesbarer:

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


/**
 * @throws LogicException Falsche Reihenfolge der Argumente
 */
public function testTwo()
{
	// ...
}

@dataProvider

Diese Anmerkung eignet sich, wenn wir die Testmethode mehrfach, aber mit unterschiedlichen Argumenten ausführen wollen. (Nicht zu verwechseln mit der gleichnamigen Annotation für Dateien).

Als Argument geben wir den Namen der Methode an, die Parameter für die Testmethode zurückgibt. Die Methode muss ein Array oder Traversable zurückgeben. Einfaches Beispiel:

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


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

Die andere Variante der Annotation @dataProvider akzeptiert einen Pfad zur INI-Datei (relativ zur Testdatei) als Argument. Die Methode wird so oft aufgerufen, wie die Anzahl der in der INI-Datei enthaltenen Abschnitte. Datei loop-args.ini:

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

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

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

und die Methode, die die INI-Datei verwendet:

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

In ähnlicher Weise können wir den Pfad zu einem PHP-Skript anstelle der INI-Datei übergeben. Es muss Array oder Traversable zurückgeben. Datei loop-args.php:

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