Protokoll und Komponenten
Das Test Anything Protocol (TAP) definiert eine textorientierte
Kommunikationsschnittstelle zwischen Programmen, die Tests
durchführen, den sogenannten Produzenten des Protokolls, und
Steuer- und Auswertungsprogrammen, die Testprogramme aufrufen,
deren Ergebnisse einsammeln und anzeigen, den sogenannten
Konsumenten des Protokolls.
-
Die semi-offizielle Spezifikation des TAP Protokolls findet sich
in dem Dokument Test::Harness::TAP.
-
Die Standard-Klasse zur Implementierung von Produzenten:
Test::Builder.
-
Die Standard-Klasse zur Implementierung von Konsumenten:
TAP::Parser.
Die genannten Klassen sind im Perl Core, also unter jeder neueren
Perl-Installation von Hause aus verfügbar.
Objektorientierte Überdeckung für Test::More
Die Klasse Test::Builder stellt eine Grundlage (Basisklasse) für
das Schreiben von Testprogrammen dar. Die Klasse erlaubt, das Test
Anything Protocol in vollem Umfang "zu sprechen". Allerdings
implementiert die Klasse nur einen begrenzten Umfang an Testmethoden:
ok is_eq is_num isnt_eq isnt_num like unlike cmp_ok
Eine andere Möglichkeit besteht darin, das Core-Modul
Test::More zu nutzen, das auf Test::Builder aufbaut
und u.a. die sehr wichtige Funktion is_deeply (Vergleich von
Datenstrukturen) zur Verfügung stellt.
Der Nachteil von Test::More ist allerdings, dass es nur eine
Funktionssammlung, keine Klasse ist. Wer objektorientiert arbeiten
möchte, findet das eventuell nicht so gut. Es lässt sich aber leicht
eine saubere objektorientierte Überdeckung für Test::More
schreiben, wenn man einige Punkte beachtet.
Hier eine objektorientierte Hülle für is_deeply, die analog
auf alle Testfunktionen von Test::More ausgedehnt werden kann:
1 use Test::More ();
2
3 sub is_deeply {
4 my ($self,$ref1,$ref2,$text) = @_;
5
6 local $Test::Builder::Level = $Test::Builder::Level + 1;
7 return Test::More::is_deeply($ref1,$ref2,$text);
8 }
Erklärung der Besonderheiten:
- Zeile 1:
-
Test::More wird geladen. Das leere Klammerpaar verhindert, dass
Funktionen des Moduls importiert und damit der Namensraum der Klasse,
in der wir die Methode definieren, verunreinigt wird.
- Zeile 6:
-
Die Variable $Test::Builder::Level definiert den Abstand auf
dem Callstack zwischen dem Aufrufer und der Testfunktion in
Test::More. Dies wird für das Reporting der genauen Codestelle
im Fehlerfall benötigt. Wir erhöhen den Abstand um 1, da wir
unsere Methode in die Aufrufhierarchie einfügen.
Für die Klassenvariable $Test::Builder::Level gilt
dynamisches Scoping.
Daher können wir ihren Wert via local lokal setzen und uns darauf
verlassen, dass beim Verlassen des Blocks automatisch der
ursprüngliche Wert wieder hergetellt wird.
- Zeile 7:
-
Wir rufen die Funktion is_deeply mit Package-Präfix voll qualifiziert
als Test::More::is_deeply auf, da wir die Test::More-Funktionen
aus gutem Grund nicht in den Namensraum der Klasse importiert haben (siehe
Erklärung zu Zeile 1).