Erste Schritte mit Nette Tester

Auch gute Programmierer machen Fehler. Der Unterschied zwischen einem guten und einem schlechten Programmierer ist, dass der gute einen Fehler nur einmal macht und ihn beim nächsten Mal mit automatisierten Tests entdeckt.

  • “Wer nicht testet, ist dazu verdammt, seine Fehler zu wiederholen.” (Sprichwort)
  • “Kaum haben wir einen Fehler beseitigt, taucht der nächste auf.” (Murphys Gesetz)
  • “Wann immer Sie versucht sind, eine print-Anweisung zu schreiben, schreiben Sie stattdessen einen Test.” (Martin Fowler)

Haben Sie in PHP schon einmal Code wie diesen geschrieben?

$obj = new MyClass;
$result = $obj->process($input);

var_dump($result);

Haben Sie also das Ergebnis eines Funktionsaufrufs ausgegeben, nur um mit dem Auge zu prüfen, ob es zurückgibt, was es soll? Wahrscheinlich machen Sie das mehrmals am Tag. Hand aufs Herz: Löschen Sie diesen Code, wenn alles richtig funktioniert? Erwarten Sie, dass die Klasse in Zukunft nicht kaputtgeht? Murphys Gesetze garantieren das Gegenteil :-)

Im Grunde haben Sie einen Test geschrieben. Er braucht nur eine kleine Änderung, damit er keine Sichtprüfung mehr verlangt, sondern sich selbst prüft. Und wenn Sie den Test nicht löschen, können Sie ihn jederzeit in der Zukunft ausführen und prüfen, ob noch alles so funktioniert, wie es soll. Mit der Zeit entsteht eine große Zahl solcher Tests, es wäre also nützlich, sie automatisch auszuführen.

Und bei all dem hilft Ihnen Nette Tester.

Was macht Tester einzigartig?

Tests für Nette Tester zu schreiben ist deshalb besonders, weil jeder Test ein ganz normales PHP-Skript ist, das sich eigenständig ausführen lässt.

Wenn Sie also einen Test schreiben, können Sie ihn einfach ausführen und feststellen, ob er zum Beispiel einen Programmierfehler enthält. Ob er richtig funktioniert. Wenn nicht, können Sie ihn in Ihrer IDE bequem durchsteppen und den Fehler suchen. Sie können ihn sogar im Browser öffnen.

Und vor allem: Indem Sie ihn ausführen, führen Sie den Test durch. Sie erfahren sofort, ob er bestanden oder fehlgeschlagen ist. Wie? Zeigen wir es. Wir schreiben einen einfachen Test für die Arbeit mit einem PHP-Array und speichern ihn in der Datei ArrayTest.php:

<?php
use Tester\Assert;

require __DIR__ . '/vendor/autoload.php';  # lädt den Composer-Autoloader
Tester\Environment::setup();               # initialisiert Nette Tester

$stack = [];
Assert::same(0, count($stack));   # wir erwarten, dass count() null zurückgibt

$stack[] = 'foo';
Assert::same(1, count($stack));   # wir erwarten, dass count() eins zurückgibt
Assert::contains('foo', $stack);  # wir prüfen, dass $stack das Element 'foo' enthält

Wie Sie sehen, dienen sogenannte Assertion-Methoden wie Assert::same() dazu, zu bestätigen, dass der tatsächliche Wert dem erwarteten Wert entspricht.

Der Test ist geschrieben, und wir können ihn von der Kommandozeile aus ausführen. Der erste Lauf zeigt eventuelle Syntaxfehler, und wenn Sie nirgends einen Tippfehler gemacht haben, wird ausgegeben:

$ php ArrayTest.php

OK

Versuchen Sie, die Zusicherung im Test in eine falsche zu ändern, etwa Assert::contains('XXX', $stack);, und sehen Sie, was beim Ausführen passiert:

$ php ArrayTest.php

Failed: ['foo'] should contain 'XXX'

in ArrayTest.php(17) Assert::contains('XXX', $stack);

FAILURE

Mit dem Schreiben von Tests machen wir im Kapitel Tests schreiben weiter.

Installation und Anforderungen

Die von Tester mindestens benötigte PHP-Version ist 8.0 (mehr Details in der Tabelle Unterstützte PHP-Versionen). Der bevorzugte Weg der Installation ist Composer:

composer require --dev nette/tester

Versuchen Sie, Nette Tester von der Kommandozeile aus zu starten (ohne Argumente gibt er nur die Hilfe aus):

vendor/bin/tester

Tests ausführen

Mit der Anwendung wächst auch die Zahl der Tests. Es wäre unpraktisch, die Tests einzeln auszuführen. Deshalb hat Tester einen Runner für die Massenausführung, den wir von der Kommandozeile aus aufrufen. Als Parameter geben wir das Verzeichnis an, in dem die Tests liegen. Ein Punkt bedeutet das aktuelle Verzeichnis.

vendor/bin/tester .

Der Test-Runner durchsucht das angegebene Verzeichnis und alle Unterverzeichnisse nach Tests, also nach Dateien *.phpt und *Test.php. Er findet auch unseren Test ArrayTest.php, denn er passt zur Maske.

Dann beginnt das Testen. Jeder Test wird als neuer PHP-Prozess gestartet, läuft also völlig isoliert von den anderen. Er führt sie parallel in mehreren Threads aus, was extrem schnell ist. Und er startet zuerst die Tests, die im vorigen Lauf fehlgeschlagen sind, sodass Sie sofort erfahren, ob Sie den Fehler beheben konnten.

Während der Ausführung gibt Tester die Ergebnisse laufend als Zeichen im Terminal aus:

  • . – Test bestanden
  • s – Test wurde übersprungen
  • F – Test fehlgeschlagen

Die Ausgabe kann so aussehen:

 _____ ___  ___ _____ ___  ___
|_   _/ __)( __/_   _/ __)| _ )
  |_| \___ /___) |_| \___ |_|_\  v2.6.0

PHP 8.5.2 (cli) | php | 8 threads

........s................F.........

-- FAILED: greeting.phpt
   Failed: 'Hello John' should be
       ... 'Hello Peter'

   in greeting.phpt(19) Assert::same('Hello Peter', $o->say('John'));

FAILURES! (35 tests, 1 failures, 1 skipped, 1.7 seconds)

Es wurden 35 Tests ausgeführt, einer ist fehlgeschlagen, einer wurde übersprungen.

Wir machen im Kapitel Tests ausführen weiter.

Watch-Modus

Refactoren Sie gerade Code? Oder entwickeln Sie sogar nach der Methodik TDD (Test Driven Development)? Dann wird Ihnen der Watch-Modus gefallen. In diesem Modus beobachtet Tester die Quellcodes und startet sich bei einer Änderung automatisch selbst.

Während der Entwicklung haben Sie in der Ecke Ihres Monitors ein Terminal, in dem Sie ein grüner Statusbalken anstrahlt, und wenn er plötzlich rot wird, wissen Sie, dass Sie gerade etwas nicht ganz richtig gemacht haben. Es ist eigentlich ein tolles Spiel, bei dem Sie programmieren und versuchen, die Farbe zu halten.

Den Watch-Modus starten Sie mit dem Parameter --watch.

Code-Coverage-Berichte

Tester kann Berichte darüber erzeugen, wie viel Quellcode die Tests abdecken. Der Bericht kann entweder im gut lesbaren HTML-Format oder als Clover XML für die weitere maschinelle Verarbeitung vorliegen.

Sehen Sie sich einen Beispiel-HTML-Bericht mit der Code Coverage an.

Unterstützte PHP-Versionen

Version Kompatibel mit PHP
Tester 2.6 PHP 8.0 – 8.5
Tester 2.5 PHP 8.0 – 8.5
Tester 2.4 PHP 7.2 – 8.2
Tester 2.3 PHP 7.1 – 8.0
Tester 2.1 – 2.2 PHP 7.1 – 7.3
Tester 2.0 PHP 5.6 – 7.3
Tester 1.7 PHP 5.3 – 7.3 + HHVM 3.3+
Tester 1.6 PHP 5.3 – 7.0 + HHVM
Tester 1.3 – 1.5 PHP 5.3 – 5.6 + HHVM
Tester 0.9 – 1.2 PHP 5.3 – 5.6

Gilt für die jeweils letzte Patch-Version.

Tester unterstützte bis Version 1.7 auch HHVM 3.3.0 oder höher (über tester -p hhvm). Ab Tester 2.0 wurde die Unterstützung eingestellt.