TestCase
********
.[perex]
In einfachen Tests können die Assertions einfach hintereinander stehen. Manchmal ist es aber vorteilhaft, die Assertions in eine Testklasse zu verpacken und sie so zu strukturieren.
Die Klasse muss `Tester\TestCase` erweitern, und wir nennen sie kurz **TestCase**. Die Klasse muss Testmethoden enthalten, deren Namen mit `test` beginnen. Diese Methoden werden als Tests ausgeführt:
```php
use Tester\Assert;
class RectangleTest extends Tester\TestCase
{
public function testOne()
{
Assert::same(/* ... */);
}
public function testTwo()
{
Assert::match(/* ... */);
}
}
# Testmethoden ausführen
(new RectangleTest)->run();
```
Ein so geschriebener TestCase lässt sich noch mit den Methoden `setUp()` und `tearDown()` erweitern. Sie werden vor bzw. nach jeder Testmethode aufgerufen:
```php
use Tester\Assert;
class NextTest extends Tester\TestCase
{
protected function setUp()
{
# Vorbereitung
}
protected function tearDown()
{
# Aufräumen
}
public function testOne()
{
Assert::same(/* ... */);
}
public function testTwo()
{
Assert::match(/* ... */);
}
}
# Testmethoden ausführen
(new NextTest)->run();
/*
Reihenfolge der Methodenaufrufe
-------------------------------
setUp()
testOne()
tearDown()
setUp()
testTwo()
tearDown()
*/
```
Tritt in der Phase `setUp()` oder `tearDown()` ein Fehler auf, schlägt der Test insgesamt fehl. Tritt ein Fehler in der Testmethode selbst auf, wird die Methode `tearDown()` trotzdem ausgeführt, Fehler in ihr werden dabei jedoch unterdrückt.
Innerhalb einer Testmethode können Sie den aktuellen Test jederzeit mit `$this->skip('Grund')` überspringen, zum Beispiel wenn eine Voraussetzung nicht erfüllt ist.
Wir empfehlen, am Anfang der Testdatei die Annotation [@testCase |test-annotations#@testCase] zu schreiben. Der Test-Runner auf der Kommandozeile führt die einzelnen Methoden des TestCase dann in eigenen Prozessen und parallel in mehreren Threads aus. Das kann den gesamten Testvorgang deutlich beschleunigen.
/--php
<?php
/** @testCase */
\--
Annotationen von Methoden
=========================
Für Testmethoden stehen mehrere Annotationen zur Verfügung, die das Testen erleichtern. Schreiben Sie sie über die Testmethode.
@throws .[filter]
-----------------
Sie entspricht der Verwendung von `Assert::exception()` innerhalb der Testmethode, die Schreibweise ist aber übersichtlicher:
```php
/**
* @throws RuntimeException
*/
public function testOne()
{
// ...
}
/**
* @throws LogicException Wrong argument order
*/
public function testTwo()
{
// ...
}
```
@dataProvider .[filter]
-----------------------
Diese Annotation ist nützlich, wenn Sie die Testmethode mehrfach mit verschiedenen Parametern ausführen wollen. (Verwechseln Sie sie nicht mit der gleichnamigen Annotation für [Testdateien |test-annotations#@dataProvider].)
Geben Sie danach den Namen einer Methode an, die die Argumente für die Testmethode liefert. Diese Methode muss ein Array oder ein Traversable-Objekt zurückgeben. Ein einfaches Beispiel:
```php
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** nimmt als Parameter den Pfad zu einer INI-Datei entgegen (relativ zur Testdatei). Die Methode wird so oft aufgerufen, wie die INI-Datei Sektionen hat. Datei `loop-args.ini`:
```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:
```php
/**
* @dataProvider loop-args.ini
*/
public function testLoop($a, $b, $c)
{
// ...
}
```
Ebenso können Sie statt einer INI-Datei auf ein PHP-Skript verweisen. Es muss ein Array oder ein Traversable-Objekt zurückgeben. Datei `loop-args.php`:
```php
return [
['a' => 1, 'b' => 2, 'c' => 3],
['a' => 4, 'b' => 5, 'c' => 6],
['a' => 7, 'b' => 8, 'c' => 9],
];
```
Wie beim [Data Provider für Testdateien |test-annotations#@dataProvider] können Sie hinter den Dateinamen eine Filterabfrage anhängen, um die Methode nur für die passenden Sektionen auszuführen.
TestCase
In einfachen Tests können die Assertions einfach hintereinander stehen. Manchmal ist es aber vorteilhaft, die
Assertions in eine Testklasse zu verpacken und sie so zu strukturieren.
Die Klasse muss Tester\TestCase erweitern, und wir nennen sie kurz TestCase. Die Klasse muss Testmethoden
enthalten, deren Namen 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(/* ... */);
}
}
# Testmethoden ausführen
(new RectangleTest)->run();
Ein so geschriebener TestCase lässt sich noch mit den Methoden setUp() und tearDown() erweitern. Sie
werden vor bzw. nach jeder Testmethode aufgerufen:
use Tester\Assert;
class NextTest extends Tester\TestCase
{
protected function setUp()
{
# Vorbereitung
}
protected function tearDown()
{
# Aufräumen
}
public function testOne()
{
Assert::same(/* ... */);
}
public function testTwo()
{
Assert::match(/* ... */);
}
}
# Testmethoden ausführen
(new NextTest)->run();
/*
Reihenfolge der Methodenaufrufe
-------------------------------
setUp()
testOne()
tearDown()
setUp()
testTwo()
tearDown()
*/
Tritt in der Phase setUp() oder tearDown() ein Fehler auf, schlägt der Test insgesamt fehl. Tritt
ein Fehler in der Testmethode selbst auf, wird die Methode tearDown() trotzdem ausgeführt, Fehler in ihr werden
dabei jedoch unterdrückt.
Innerhalb einer Testmethode können Sie den aktuellen Test jederzeit mit $this->skip('Grund') überspringen,
zum Beispiel wenn eine Voraussetzung nicht erfüllt ist.
Wir empfehlen, am Anfang der Testdatei die Annotation @testCase zu schreiben. Der Test-Runner auf der Kommandozeile
führt die einzelnen Methoden des TestCase dann in eigenen Prozessen und parallel in mehreren Threads aus. Das kann den gesamten
Testvorgang deutlich beschleunigen.
<?php
/** @testCase */
Annotationen von Methoden
Für Testmethoden stehen mehrere Annotationen zur Verfügung, die das Testen erleichtern. Schreiben Sie sie über die
Testmethode.
@throws
Sie entspricht der Verwendung von Assert::exception() innerhalb der Testmethode, die Schreibweise ist aber
übersichtlicher:
/**
* @throws RuntimeException
*/
public function testOne()
{
// ...
}
/**
* @throws LogicException Wrong argument order
*/
public function testTwo()
{
// ...
}
@dataProvider
Diese Annotation ist nützlich, wenn Sie die Testmethode mehrfach mit verschiedenen Parametern ausführen wollen. (Verwechseln
Sie sie nicht mit der gleichnamigen Annotation für Testdateien.)
Geben Sie danach den Namen einer Methode an, die die Argumente für die Testmethode liefert. Diese Methode muss ein Array oder
ein Traversable-Objekt 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 nimmt als Parameter den Pfad zu einer INI-Datei entgegen (relativ zur
Testdatei). Die Methode wird so oft aufgerufen, wie die INI-Datei Sektionen hat. 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)
{
// ...
}
Ebenso können Sie statt einer INI-Datei auf ein PHP-Skript verweisen. Es muss ein Array oder ein Traversable-Objekt
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],
];
Wie beim Data Provider für Testdateien können Sie
hinter den Dateinamen eine Filterabfrage anhängen, um die Methode nur für die passenden Sektionen auszuführen.