Test-Annotationen

Annotationen bestimmen, wie Tests vom Kommandozeilen-Teststarter behandelt werden. Sie werden am Anfang der Testdatei geschrieben.

Bei Annotationen wird die Groß-/Kleinschreibung nicht berücksichtigt. Sie haben auch keine Auswirkung, wenn der Test manuell als normales PHP-Skript ausgeführt wird.

Beispiel:

/**
 * TEST: Grundlegender Datenbankabfragetest.
 *
 * @dataProvider files/databases.ini
 * @exitCode 56
 * @phpVersion < 5.5
 */

require __DIR__ . '/../bootstrap.php';

TEST

Dies ist eigentlich keine Annotation, sondern bestimmt nur den Titel des Tests, der bei einem Fehlschlag oder im Protokoll ausgegeben wird.

@skip

Der Test wird übersprungen. Nützlich zum vorübergehenden Deaktivieren von Tests.

@phpVersion

Der Test wird übersprungen, wenn er nicht mit der entsprechenden PHP-Version ausgeführt wird. Die Annotation wird als @phpVersion [Operator] Version geschrieben. Der Operator kann weggelassen werden, der Standard ist >=. Beispiele:

/**
 * @phpVersion 5.3.3
 * @phpVersion < 5.5
 * @phpVersion != 5.4.5
 */

@phpExtension

Der Test wird übersprungen, wenn nicht alle angegebenen PHP-Erweiterungen geladen sind. Mehrere Erweiterungen können in einer Annotation angegeben oder die Annotation kann mehrfach verwendet werden.

/**
 * @phpExtension pdo, pdo_pgsql, pdo_mysql
 * @phpExtension json
 */

@dataProvider

Wenn wir eine Testdatei mehrfach, aber mit unterschiedlichen Eingabedaten ausführen möchten, ist diese Annotation nützlich. (Nicht zu verwechseln mit der gleichnamigen Annotation für TestCase.)

Wir schreiben sie als @dataProvider file.ini, der Pfad zur Datei wird relativ zur Testdatei interpretiert. Der Test wird so oft ausgeführt, wie es Abschnitte in der INI-Datei gibt. Angenommen, die INI-Datei databases.ini lautet:

[mysql]
dsn = "mysql:host=127.0.0.1"
user = root
password = ******

[postgresql]
dsn = "pgsql:host=127.0.0.1;dbname=test"
user = postgres
password = ******

[sqlite]
dsn = "sqlite::memory:"

und im selben Verzeichnis der Test database.phpt:

/**
 * @dataProvider databases.ini
 */

$args = Tester\Environment::loadData();

Der Test wird dreimal ausgeführt, und $args enthält jeweils die Werte aus den Abschnitten mysql, postgresql oder sqlite.

Es gibt noch eine Variante, bei der wir die Annotation mit einem Fragezeichen als @dataProvider? file.ini schreiben. In diesem Fall wird der Test übersprungen, wenn die INI-Datei nicht existiert.

Damit sind die Möglichkeiten der Annotation noch nicht erschöpft. Hinter dem Namen der INI-Datei können wir Bedingungen angeben, unter denen der Test für den jeweiligen Abschnitt ausgeführt wird. Erweitern wir die INI-Datei:

[mysql]
dsn = "mysql:host=127.0.0.1"
user = root
password = ******

[postgresql 8.4]
dsn = "pgsql:host=127.0.0.1;dbname=test"
user = postgres
password = ******

[postgresql 9.1]
dsn = "pgsql:host=127.0.0.1;dbname=test;port=5433"
user = postgres
password = ******

[sqlite]
dsn = "sqlite::memory:"

und verwenden die Annotation mit einer Bedingung:

/**
 * @dataProvider  databases.ini  postgresql, >=9.0
 */

Der Test wird nur einmal ausgeführt, und zwar für den Abschnitt postgresql 9.1. Die anderen Abschnitte bestehen den Bedingungsfilter nicht.

Ähnlich können wir anstelle einer INI-Datei auf ein PHP-Skript verweisen. Dieses muss ein Array oder Traversable zurückgeben. Datei databases.php:

return [
	'postgresql 8.4' => [
		'dsn' => '...',
		'user' => '...',
	],

	'postgresql 9.1' => [
		'dsn' => '...',
		'user' => '...',
	],
];

@multiple

Wird als @multiple N geschrieben, wobei N eine ganze Zahl ist. Der Test wird genau N-mal ausgeführt.

@testCase

Die Annotation hat keine Parameter. Wir verwenden sie, wenn wir Tests als TestCase-Klassen schreiben. In diesem Fall führt der Kommandozeilen-Teststarter die einzelnen Methoden in separaten Prozessen und parallel in mehreren Threads aus. Dies kann den gesamten Testprozess erheblich beschleunigen.

@exitCode

Wird als @exitCode N geschrieben, wobei N der Rückgabecode des ausgeführten Tests ist. Wenn im Test beispielsweise exit(10) aufgerufen wird, schreiben wir die Annotation als @exitCode 10, und wenn der Test mit einem anderen Code endet, wird dies als Fehlschlag betrachtet. Wenn die Annotation nicht angegeben wird, wird der Rückgabecode 0 (Null) überprüft.

@httpCode

Die Annotation wird nur angewendet, wenn die PHP-Binärdatei CGI ist. Andernfalls wird sie ignoriert. Wird als @httpCode NNN geschrieben, wobei NNN der erwartete HTTP-Code ist. Wenn die Annotation nicht angegeben wird, wird der HTTP-Code 200 überprüft. Wenn NNN als Zeichenkette geschrieben wird, die zu Null ausgewertet wird, z. B. any, wird der HTTP-Code nicht überprüft.

@outputMatch und @outputMatchFile

Die Funktion der Annotationen ist identisch mit den Assertions Assert::match() und Assert::matchFile(). Das Muster (Pattern) wird jedoch im Text gesucht, den der Test an seine Standardausgabe gesendet hat. Dies findet Anwendung, wenn wir davon ausgehen, dass der Test mit einem fatalen Fehler endet und wir dessen Ausgabe überprüfen müssen.

@phpIni

Legt für den Test Konfigurations-INI-Werte fest. Wird beispielsweise als @phpIni precision=20 geschrieben und funktioniert genauso, als ob wir den Wert von der Kommandozeile über den Parameter -d precision=20 angegeben hätten.