Qualitätseigenschaften von Testfällen

Oct 07
2009

Testen bedeutet ein systematisches Überprüfen des zu prüfenden Systems. Die Qualität der Testing Aktivitäten wird also wesentlich bestimmt durch die Frage, wie systematisch diese Überprüfung stattfindet.

Ein einzelnes Prüfszenario wird als ein Testfall bezeichnet. Ein Testfall soll ein bestimmtes Kriterium beleuchten und allfällige Probleme ans Tageslicht bringen. In diesem Kapitel geht es darum zu definieren, was einen guten Testfall ausmacht und wie solche Testfälle gefunden werden können.

Testfälle sind DER Rohstoff, auf dem sich ein erfolgreiches Testing aufbauen lässt. Verschiedene der folgenden Themen wie z.B. die Testautomatisierung sind vollständig von diesem Rohstoff abhängig. Wenn die falschen Testfälle gewählt werden, nützt es auch nichts, sie so raffiniert und effizient wie möglich auszuführen. Der Erfolg kann damit nicht herbeigeführt werden. Die Summe der Testfälle sind das Herzstück eines Testprozesses.

Was sind denn nun die Eigenschaften guter Testfälle?

Testfälle weisen unabhängig vom zu testenden System einige Qualitätsmerkmale auf, die allgemeine Gültigkeit haben. Diese Eigenschaften tragen alle zur Qualität eines Testfalles bei. Sie sind aber nicht als absolute Regeln zu betrachten, sondern als Leitlinien bzw. als Vision. Es ist in den verschiedenen Kontexten immer wieder notwendig, bei einzelnen Kriterien Abstriche zu machen, um das Ziel mit einem sinnvollen Aufwand zu erreichen.

  • Klare Zielsetzung: Es ist für jeden Testfall eindeutig, welche Abläufe, Eigenschaften und Konstellationen mit diesem Testfall überprüft werden. Diese Information ist so zugänglich, dass nachvollziehbar ist, warum dieser Testfall relevant und wichtig ist. Im Besonderen bei der Wartung der Testfälle und beim Entscheid, ob ein Testfall immer noch relevant ist oder ob es redundante Testfälle gibt, die eliminiert werden können, ist diese Information essentiell.
  • Messbarer Erfolg: Ein Testfall hat nur zwei mögliche Resultate: Success oder Failure. Um zu entscheiden, ob ein Testfall nun erfolgreich ausgeführt wurde oder nicht, braucht es Verifikationspunkte, die sicherstellen, dass sich das System under Test so verhält, wie es sollte. Ein Testfall ohne Verifikationspunkte kann nur aussagen, dass man “irgendwie durchgekommen ist, ohne dass das System zusammengebrochen ist”. Das ist als Aussage aber zu schwach.
  • Wiederholbarkeit: Ein Testfall, der zwei Mal unter den selben Bedingungen ausgeführt wird, muss das gleiche Resultat ergeben. Dies ist in der Theorie einleuchtend, in der Praxis aber oft nicht so leicht zu realisieren, da die Aussage “mit den selben Bedingungen” eigentlich nicht realisierbar ist. Verschiedene Umgebungsparameter spielen hier hinein: Was für andere Prozesse laufen noch auf dem System? Wie ist die aktuelle Auslastung des Netzwerks? etc. Dennoch müssen Testfälle, die häufiger diese Eigenschaft verletzen, analysiert und überdacht werden, da ansonsten eine vernünftige Nachvollziehbarkeit nicht gegeben ist und ein damit verbundener allfälliger Fehlereintrag für den Entwickler wenig hilfreich, der den Fehler beheben soll.
  • Unabhängigkeit: Jeder Testfall soll einen in sich geschlossenen Ablauf darstellen. Er soll nicht auf dem Resultat eines anderen Testfalls basieren. Die Reihenfolge der Testfälle innerhalb einer Testsuite soll keine Rolle spielen. Dieser Punkt wird oft zu schnell und leichtfertig geopfert, um damit Aufwand zu sparen, indem z.B. das Datensetup eines Testfalls nicht mehr erstellt werden muss, da ein anderer Testfall die Testdaten im entsprechenden Zustand zurücklässt. Der Preis, der dafür bezahlt werden muss, ist nicht zu unterschätzen. Fehler in einem vorangehenden Testfall können folgende Testfälle zu Fall bringen, obwohl die zu prüfende Funktionalität des nachfolgenden Testfalls eigentlich korrekt funktioniert. Ein Fehler kann andere Probleme maskieren, indem die Testsuite gar nie zu den Folgeproblemen kommt, weil schon der erste Fehler die folgenden verdeckt. Und im Weiteren ist es äusserst schwierig, diese Abhängigkeiten zwischen Testfällen zu überblicken und zu warten.Wenn es vom Setting her irgenwie möglich ist, sollte also jeder Testfall in seinem eigenen Universum arbeiten, das unabhängig von allen anderen Testfällen ist. Das heisst, dass er für sein gesamtes Setup (ev. den Programmstart, die Initialisierung des Datenzustandes und das entsprechende Aufräumen nach der Durchführung) selber verantwortlich ist. Dieser Grundsatz führt zu erheblich stabileren Testdurchläufen und zu aussagekräftigeren Resultaten.
  • Keine unnötigen Überprüfungen: Nach der Erkenntnis, dass Testfälle ohne Verifikation wenig bis nichts aussagen, folgt oft der gegenteilige Effekt, dass nach jedem Schritt alles überprüfbare auch tatsächlich verifiziert wird. Dagegen sprechen vor allem zwei Punkte: Der Aufwand bei der Testdurchführung und die Wartbarkeit. Der Aufwand bei der Testdurchführung ist offensichtlich. Wenn nach jedem Testschritt diverse Verifikationen durchgeführt werden, ergibt eine enorme Menge von Aktionen. Das kann sich z.B. bei der Automatisierung einer grossen Menge von Testfällen so stark ins Gewicht fallen, dass die Testsuite nicht mehr in der vorhandenen Zeit durchläuft. Der zweite Punkt ist über die gesamte Laufzeit eines Projekts und Systems aber meist der gewichtigere. Wenn sich am System eine Änderung ergibt, die eine bestimmte Verifikation betrifft, so müssen nicht nur die Testfälle, die auf diesen Punkt fokussieren, angepasst werden, sondern alle, die irgendwann im Lauf des Testfalls an diesem Punkt vorbeikommen, auch wenn es im entsprechenden Testfall eigentlich um etwas ganz anderes geht.

2 Responses to “Qualitätseigenschaften von Testfällen”

  1. Uwe says:

    OK, ich geb’s zu, ich bin auf Dein Blog nur gekommen, weil ich einen Google Alert auf “Testfälle” laufen haben, weil wir eine Software zum Verwalten von eben solchen Testfällen haben.

    Aber: Ich find’s trotzdem sehr interessant was Du schreibst und habe Dein Weblog gleich mal in meinem Google Reader abonniert 🙂

  2. Zeljko says:

    Hi Thomas,
    habe vorhin deinen Blog entdeckt. 😉

    Die Unabhängigkeit von Tests finde ich auch wichtig, aber schon als Entwickler habe ich Setup-Methoden für die ganze Testklasse geschrieben (Integrationstests). Mit JUnit 4 kam dann @BeforeClass hinzu. Das Problem bei Setups pro Testmethode war oft, dass die Performance stark sank, vor allem dann, wenn der Setup für viele der Testmethoden ähnlich ist und jedesmal viel Zeit kostet.

    In einem anderen Projekt war es manchmal so, dass bei Systemtests der Setup von einigen Datenkonstellationen bereits mehrere einzelne Tests in sich darstellte. Diese brauchten auch längere Zeit, sodass die Daten-schaffenden und -manipulierenden Tests aufeinander aufbauten. Der Nachteil war, dass bei Fehlern weniger Tests insgesamt durchgeführt wurden. Je stabiler die getestete Anwendung ist, umso weniger wirkte sich das aus, und es gab eine wesentlich bessere Performance der Testsuite.

    Mit einem JUnit-Addon namens JExample konnte ich Depencies zwischen den Testfällen definieren. Schlug Test A fehl, dann wurde z.B. Test B gar nicht ausgeführt. Dadurch gab es keine Folgefehler in anderen Testfällen.

    Unabhängig von möglicherweise starken Performance-Verlusten möchte man vielleicht explizit eine Abhängigkeit zwischen zwei Testfällen definieren. Wenn z.B. der LogonTest nicht funktioniert, dann kann der LogoutTest logisch gesehen nicht funktionieren, da er zuerst ein Logon erfordert.

    Vielleicht ergibt sich einmal die Gelegenheit, dass ein wenig zu diskutieren.

    Dem Punkt “Keine unnötigen Überprüfungen” stimme ich zu, würde aber gerne hinzufügen, dass es Sinn machen kann, dann Validierungen zu verwenden, wenn man Folgefehler im gleichen Test ausschliessen möchte und sie nicht zuviel Performance und Wartungsaufwand kosten. Vorteil: kürzere Fehlerwirkungsanalysezeit und ggf. passendere Fehlermeldungen.

Leave a Reply

Categories