TestCase
In einfachen Tests können Assertions aufeinander folgen. Manchmal ist es jedoch vorteilhafter, Assertions in einer Testklasse zu verpacken und sie so zu strukturieren.
Die Klasse muss von Tester\TestCase
erben und wird vereinfacht als testcase bezeichnet. Die Klasse muss
Testmethoden enthalten, die mit test
beginnen. Diese Methoden werden als Tests ausgeführt:
use Tester\Assert;
class RectangleTest extends Tester\TestCase
{
public function testOne()
{
Assert::same(/* ... */);
}
public function testTwo()
{
Assert::match(/* ... */);
}
}
# Ausführung der Testmethoden
(new RectangleTest)->run();
Ein so geschriebener Test kann weiter um Methoden setUp()
und tearDown()
erweitert werden. Sie werden
vor bzw. nach jeder Testmethode aufgerufen:
use Tester\Assert;
class NextTest extends Tester\TestCase
{
public function setUp()
{
# Vorbereitung
}
public function tearDown()
{
# Aufräumen
}
public function testOne()
{
Assert::same(/* ... */);
}
public function testTwo()
{
Assert::match(/* ... */);
}
}
# Ausführung der Testmethoden
(new NextTest)->run();
/*
Reihenfolge der Methodenaufrufe
-------------------------------
setUp()
testOne()
tearDown()
setUp()
testTwo()
tearDown()
*/
Wenn in der setUp()
- oder tearDown()
-Phase ein Fehler auftritt, schlägt der Test insgesamt fehl.
Wenn in der Testmethode ein Fehler auftritt, wird die Methode tearDown()
dennoch ausgeführt, jedoch mit
unterdrückten Fehlern darin.
Wir empfehlen, am Anfang des Tests die Annotation @testCase zu schreiben. Dann führt der Kommandozeilen-Teststarter die einzelnen Methoden des Testcases in separaten Prozessen und parallel in mehreren Threads aus. Dies kann den gesamten Testprozess erheblich beschleunigen.
<?php
/** @testCase */
Annotationen von Methoden
Für Testmethoden stehen uns mehrere Annotationen zur Verfügung, die uns das Testen erleichtern. Wir schreiben sie zur Testmethode.
@throws
Ist äquivalent zur Verwendung von Assert::exception()
innerhalb der Testmethode. Die Schreibweise ist jedoch
übersichtlicher:
/**
* @throws RuntimeException
*/
public function testOne()
{
// ...
}
/**
* @throws LogicException Wrong argument order
*/
public function testTwo()
{
// ...
}
@dataProvider
Wenn wir eine Testmethode mehrfach, aber mit unterschiedlichen Parametern ausführen möchten, ist diese Annotation nützlich. (Nicht zu verwechseln mit der gleichnamigen Annotation für Dateien.)
Dahinter geben wir den Namen der Methode an, die die Argumente für die Testmethode zurückgibt. Die Methode muss ein Array oder Traversable zurückgeben. Ein einfaches Beispiel:
public function getLoopArgs()
{
return [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
];
}
/**
* @dataProvider getLoopArgs
*/
public function testLoop($a, $b, $c)
{
// ...
}
Die zweite Variante der Annotation @dataProvider akzeptiert als Parameter den Pfad zu einer INI-Datei (relativ zur
Testdatei). Die Methode wird so oft aufgerufen, wie es Abschnitte in der INI-Datei gibt. 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)
{
// ...
}
Ähnlich können wir anstelle einer INI-Datei auf ein PHP-Skript verweisen. Dieses muss ein 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],
];