Richard Voß: Tests / Qualitätssicherung - aber wie?

Beitrag lesen

Allgemein lässt sich wenig formulieren. Ich schreibe zu jedem Modul(ich verwende fast nur Perl) sofort einen Test in einem Testverzeichnis (t/), den ich per :vsplit immer rechts neben dem eigentlichen Code habe und über F9 schlagartig durchlaufen kann. Dadurch kann ich auch tesgetriebene Entwicklung (http://www.wikiservice.at/dse/wiki.cgi?TestgetriebeneEntwicklung) betreiben.

D.h. von vorn herein sollte alles, was du schreibst, modularisiert sein, in Bibliotheken und Klassen. Solche lassen sich dann auch einzeln auf Herz und Nieren testen. Afaik gibt es die Möglichkeit PHP auch auf der Kommandozeile zu interpretieren, also kannst du es im Grunde auch gleich dort beim Entwickeln testen. Ansonsten schreib' halt ein einfaches Testprogramm, das auf dem Webserver die jeweilige Komponente prüft. Ob es so tolle Testframeworks wie Test::More für Perl auch für PHP gibt, weiß ich nicht.

Das "Ganze" Projekt läuft, wenn die einzelnen Teile tun, was sie sollen. Fehler, die dazwischen liegen, können dann durch Betatetester gefunden werden. Die Ganzen Kleinigkeiten in den Komponenten müssen im Beta-Zustand schon eliminiert sein, weil man sonst gar keine lauffähige Betaphase bekommt, sondern nur hunderte Fehler.

Deswegen lohnt es sich spätestens beim Testen, _korrekt_ modularisiert zu haben, denn wenn alles unübersichtlich ineinander verzahnt ist, lassen sich keine wirkichen Test schreiben, sondern nur Stichproben.

Ich hoffe also, deine 200 PHP-Dateien lassen sich alle isoliert testen, d.h. du schreibst 200 Tests, die jeweils nur die korrekte Funktionalität einer Datei prüfen. Wenn die Dateien so beschaffen sind, dass sie einen komplizierten Kontext brauchen, hast du ein Problem, dann musst du diesen Kontext nämlich im test simulieren.

Warum du auf Komponentenebene testen solltest, lässt sich mathematisch begründen:

Wenn jede Komponente n eine Anzahl potentieller Fehler a(n) hat (jede Funktion/Methode enthält mindestens einen potentiellen Fehler), dann ist die Anzahl der zu testenden Fälle für die Komponente a(n), alle Komponenten veruraschen dann also die Summe aller a(n) an Tests.

Testet man nur das komplette System, dürfte die Anzahl der Tests schlimmstenfalls das Produkt aller a(n) sein, wenn nämlich jede Komponente auf jede zugreift. Da das selten der Fall ist, ist auch die Testanzahl nicht ganz so hoch, aber niemals so gering wie beim Komponententest. Die Testfälle werden mehr, entfernen sich aber nicht voneinander, d.h. sie unterscheiden sich untereinander kaum und es werden garantiert welche übersehen.

Zum konkreten Testen in PHP weiß ich nichts. In Perl gibt es eine Konvention über die Ausgabe von Testprogrammen. Das sieht etwa so aus (schreibe ich gerade aktuell):

1..43
ok 1 - use Pie::Object;
ok 2 - Pie::Parent->create
ok 3 - The object isa Pie::Parent
ok 4 - The object isa Pie::Object
ok 5 - Pie::Object->new(parent)
ok 6 - The object isa Pie::Object
[...]
ok 38 - o1->push_stack
ok 39 - o2->push_stack
ok 40 - o1->run_stack walks up
ok 41 - ... in correct order (0 1 2 3 4 5)vs(0-5)
ok 42 - o2->run_stack walks up twice
ok 43 - ... in correct order (0 1 2 3 4 5 6 7 8 9 10 11 12)vs(0-12)

Diese Ausgabe wird dann wiederum von Programmen ausgewertet, die nur noch die Testinformationen von gescheiterten Tests ausgeben. So kann exakt festgestellt werden, ob und welche Test scheitern.
Das Testpogramm selbst sieht so aus:

#!/usr/bin/perl
use strict;
use warnings;

use Test::More qw/tests 43/;
use Test::Exception;

our $CLASS;

BEGIN{
        $CLASS = 'Pie::Object';
        use_ok($CLASS)
                or die "use $CLASS failed";
}

ok(
        my $parent = Pie::Parent->create(),
        'Pie::Parent->create' );
isa_ok( $parent , 'Pie::Parent' );
isa_ok( $parent , 'Pie::Object' );

[...]

Das waren die ersten 4 von 43.
Es dürfte kaum sehr kompliziert sein, solche Programme auch in PHP zu schreiben.

Es kommt jetzt also darauf an, wie sauber dein Design ist.