Einhundert Prozent Testabdeckung
 
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern

100 % Testabdeckung bedeutet, dass keine Änderung am Produktionscode durchgeführt werden kann, ohne dass ein Test fehl schlägt. Die Abdeckung kann sich auf UnitTests, auf AkzeptanzTests oder auf beide Testarten beziehen. Eine hohe bis perfekte Abdeckung kann der Entwickler erreichen, indem er XP-Techniken wie TestFirst bzw. TestgetriebeneEntwicklung anwendet.

Es ist umstritten, ob wirklich eine 100 %ige Abdeckung erforderlich ist und nicht vielleicht sogar unwirtschaftlich sein könnte. Unbestritten kann aber eine 100 %-Marke uninterpretiert als qualitätiv hochwertig betrachtet werden, während eine Marke kleiner 100 % einer Interpretation bedarf: welcher Schwellwert ist noch ausreichend oder wurde nur Unwesentliches nicht getestet? Letzteres Bedarf meist eines ausgiebigen Reviews des Codes, was langwierig und somit teuer sein dürfte.

Entwickler, die die 100 % für nicht so wichtig halten, meinen, dass einfach zu viele Tests geschrieben würden, welche den Entwickler mehr behindern denn unterstützen. Diese Entwickler beschränken sich statt dessen lediglich auf das Testen von Logik beeinhaltenden Produktionscode. Somit fallen einfache Getter und Setter, welche lediglich Instanzvariablen veräußern, als zu testenden Methoden weg. Die toString()-Methode, welche als Debugausgabe eines Objektes zu benutzen ist, braucht demnach ebenfalls nicht getestet zu werden. Auch JavaBeans, welche keine Logik beeinhalten und auch Wertobjekte sind es häufig nicht Wert, getestet zu werden.

Andererseits gibt es Entwickler, die die 100 %-Marke anstreben und den Code erst dann als getestet sowie das Release erst dann ausliefern, wenn der komplette Code mit Tests abgedeckt ist. Und oftmals werden interessante Designmängel aufgedeckt, indem die letzten 2 % ungetesteten Code näher untersucht werden.

Um die Testabdeckung festzustellen, existieren sog. Wiki:CodeCoverageTools, wie z. B. Wiki:JesTer oder CortexClover?.

Links

Diskussion

100 % Testabdeckung sind nach obiger Definition durch einen simplen Sourcecodevergleich zu erzielen. Damit wird bereits das Kritikpotential deutlich. Weiter ist anzumerken, dass sich mit zunehmendem Testcode auch für diesen die Frage nach Fehlern und Designschwächen stellt.

Naja, ein Duplikat des Sourcecodes als Regressionstest zu benutzen ist doch ein ziemlich zweifelhafter Ansatz zur Testabdeckung, wenn ich Dir auch recht geben muss, dass die 100 % Testabdeckung per Definition damit erfüllt ist. Fällt Dir eine passendere Definition hierzu ein? Ich werd' auch nochmal überlegen... Und was den Testcode selbst angeht: per Wiki:CodeCoverageTools soll auch der Testcode zu untersuchen sein. Soetwas habe ich aber bislang nicht gemacht. --bs

Beim Schreiben der Antwort auf Helmuts Fragen kam mir diese Definition in den Sinn: "100 % Testabdeckung bedeutet, dass jede Anweisung des Codes mindestens einmal durchlaufen wird beim Ausführen aller Tests." Was meint ihr dazu? --bs

Es gibt Tools, die das so messen. Aber wie Helmut unten andeutet, kann man das leicht anders interpretieren. Damit entfernst du dich drastisch von der erstgenannten Definition, dass bei 100 % Abdeckung Änderungen im Programm auffallen müssen. Da das Problem nicht neu ist, gibt es vmtl. bereits Begriffe für die verschiedenen Abdeckungen. -- SDö

Welche? Machst mich neugierig; über Hilfe bzgl. der Definition würde ich mich sehr freuen, denn es war lediglich ein erster Wurf. --bs

Ich kenne da primär Zeug aus dem Smalltalkbereich (SUnit und Testmentor), das wird dir nicht großartig weiterhelfen. Eine Testsuite, bei der jede Zeile Code einmal durchlaufen wird, ist schon ein prima Ergebnis und macht bereits eine Menge Arbeit. Will man die möglichen Kombinationen erfassen, ist man vermutlich auf statische Typisierung angewiesen.

Wo ist die Referenz für 100 % und wie könnte das sichergestellt werden? Nehmen wir an, wir testen eine Routine, die eine 32-bit-Multiplikation durchführt. Was bedeutet hier 100 % Abdeckung? Doch wohl nicht, wenn jede der 2^64 möglichen Parameterkombinatinonen getestet wird? Welche Fälle müssen getestet werden? -- HelmutLeitner

100 % ist eine Metrik und diese lässt sich mit entsprechenden Tools (siehe oben) erfassen. Diese Metrik könnte z. B. während eines Builds automatisch ermittelt werden und verhindern, dass qualitativ minderwertiger Code integriert oder ein Release veröffentlich wird. Was Dein Beispiel angeht: ein Test, der alle möglichen Kombinationen durchläuft, hätte a) ebensoviel Logik wie der zu testende Code und wäre b) viel zu aufwändig. Möchtest Du solche Maßstäbe an Qualität ansetzen, so wäre eine Verifikation wohl das passendere Mittel hier. Normalerweise würden ein paar Grenztests und Äquivalenztestklassen ausreichen, um den Code zu testen. Eine Testabdeckung per Code Coverage Tool wie CortexClover? bedeutet, dass jede Anweisung des Codes mindestens einmal durchlaufen wird, wenn alle Tests ausgeführt werden. (Hey, das wär doch eine gute Definition? Gleich mal Sascha fragen :-) ) In deinem Beispiel sollten also auch alle Anweisungen von den Tests "benutzt" werden. Manuell kannst Du das auch machen (aber viel aufwändiger!): lasse alle Tests grün laufen und dann lösche jeweils eine Anweisung und lasse die Tests erneut durchlaufen. Bei einer gelöschten Anweisung und einem roten Testdurchlauf ist alles okay, bei einem grünen Testdurchlauf ist entweder a) die gerade gelöschte Anweisung überflüssig gewesen oder b) ein für den Code wichtiger Test wurde vergessen. --bs

Ich versteh nicht, was gemeint ist. Kann bitte jemand mal ein Beispiel für "100 % Testabdeckung bedeutet, dass keine Änderung am Produktionscode durchgeführt werden kann, ohne dass ein Test fehl schlägt." geben? Ich gebe den zu testenden Produktionscode (Programmiersprache C) vor, hier ist er:
int sieben() { 7; return 5; }
Ich hoffe, er ist nicht zu kompliziert für euch. Auch noch die Anforderungs-Dokumentation dazu: "Die Funktion 'sieben()' liefert den int-Wert 5.". Wie gelangt ihr also bei diesem Beispiel zur von euch genannten "100 % Testabdeckung"? Bitte kein Geschwalle, sondern ausführbaren Testcode. -- VolkerGlave

assertEquals(5, sieben());
sollte als Test hierfür ausreichen. Damit hast Du keine 100 % erreicht. CortexClover? würde Dir zwar 100 % bescheinigen, da Du jede Anweisung des Produktionscodes beim Ausführen der Tests durchläufst. Wiki:JesTer dagegen, als Tool fürs Wiki:MutationTesting, würde Dir einen Fehler melden, denn es könnte die 7 in eine andere Zahl ändern, und der Test würde trotzdem noch grün laufen. Insofern ist Dein Code verbesserungsfähig, und soetwas wird Dir gezeigt, wenn Du eine EinhundertProzentTestabdeckung anstrebst. Damit hast Du, sobald der Fehler beseitigt wird, eine 100 %-Testabdeckung erreicht. --bs

Für Nicht-"100 % Testabdeckung" hast du einen Testcode angegeben, warum keinen Testcode für "100 % Testabdeckung"? -- Volker

Weil Du einen teilweise nicht testbaren Code abgeliefert hast. Was Du nicht testen kannst, kannst Du auch schlecht mit Tests abdecken. Abgesehen davon habe ich Testcode für "100 % Testabdeckung" angegeben, nur mußt Du Deinen Produktionscode wie oben angegeben noch entsprechend bereinigen. Worauf willst Du hinaus? --bs

Ich will nirgends drauf hinaus, ich habe lediglich noch nicht verstanden (vielleicht, weil du es noch nicht verständlich genug gemacht hast), was mit diesem "100 % Testabdeckung" gemeint ist. So verstehe ich nicht, wieso der Beispielcode "teilweise nicht testbar" ist. Schließlich ist er (nebenbei bemerkt: vermutlich korrekt) ablauffähig. Selbst wenn ich es verstünde, und du zudem Recht hättest, dass der Beispielcode für "100 % Testabdeckung" nicht testbar ist, was soll das für ein tolles Testsystem sein, mit dem sich ablauffähiger Code nicht testen lässt? -/- Du hast übrigens nicht, wie von dir behauptet, Testcode für "100 % Testabdeckung" angegeben. Der einzige von dir angegebene Testcode ist "assertEquals(5, sieben());", und von dem sagst du selbst, er erreiche die "100 % Testabdeckung" nicht. -/- Gut, du hast dich oben an der 7 gestört. Auch da verstehe ich zwar wieder nicht, warum - ich finde es jedenfalls ungewöhnlich, dass man bereits vor der Erstellung des Testcodes zum Ändern des Produktionscodes aufgefordert wird -, aber gut, ich kann die 7 gerne weglassen. Der Produktionscode sieht jetzt also so aus:
int sieben() { ; return 5; }
Und nun würde ich gerne den Testcode für den zugehörigen "100 % Testabdeckung"-Test sehen. -- Volker

Meine Interpretation: Nicht testbar ist Code ohne Auswirkung auf Rückgabewert und ohne Seiteneffekt. Soetwas decken manchmal statische Analysewerkzeuge auf. Zum Beispiel warnen selbst Smalltalk-Bytecode-Compiler vor Statements ohne Effekt. Ein Testwerkzeug, welches misst, ob in einer Testsuite jeder Ausführungszweig einer Methode durchlaufen wurde, wird einen anderen Messwert ausspucken, als ein Werkzeug, welches nur misst, ob jede Methode einmal durchlaufen wurde. Will sagen: Erst wenn man definiert, was mit "Testabdeckung" gemeint ist, wird man sich mit Prozenten beschäftigen können. Ob mit oder ohne die 7. Ich würde der oben wiedergegebenen Assertion eine vollständige Testabdeckung zusprechen. Über NOPs im Quellcode zu diskutieren, die eh wegoptimiert werden, macht ja wohl wenig Sinn. -- SDö

Oben steht "100 % Testabdeckung bedeutet, dass keine Änderung am Produktionscode durchgeführt werden kann, ohne dass ein Test fehl schlägt.". Ich habe Produktionscode geliefert. Wie sieht der (zur vorstehenden Aussage passende) Testcode aus? Ist das so schwer zu begreifen, dass ich den Testcode sehen will? -/- Was hängt ihr euch alle so an der 7 auf? Sie steht so nun einmal im zu testenden Produktionscode. Warum nicht. Könnte ausführlicher auch so aussehen ...
int sieben() {
    // Marker für unser Firmen-Analysetool BROWSE_HELPER
    7;
    // Wert laut Anforderungs-Dokumentation liefern
    return 5;
}
..., basta. -- Volker, weiter auf den Testcode wartend.

Aber Du hast schon mitbekommen, dass die obige Definition nur ein erster Wurf ist? Ein weiterer Vorschlag von mir (weiter oben steht der schonmal) war: "100 % Testabdeckung bedeutet, dass jede Anweisung des Codes mindestens einmal durchlaufen wird beim Ausführen aller Tests." Ich würde mittlerweile sagen, dass die obige Definition für Wiki:Jester, die gerade genannte für Clover gelten sollte.
Was die 7 angeht, für den Fall, dass es keine NOP ist: um diese Anforderung ("Soll vom Firmen-Analysetool {BROWSE HELPER}? bearbeitbar sein.") zu testen müsste ich mehr wissen, wie der {BROWSE HELPER}? arbeitet. Dann könnte man das auch testen, soetwas wie
 assertEquals(7, BROWSE_HELPER.get(0)); 
, aber wie geschrieben, da bräuchte ich mehr Infos drüber.
Sollte die 7 nur eine NOP sein (wie ein alleiniges ; auch eine NOP ist und z. B. auch von Java ab 1.4 nicht mehr zulässig ist bzw. beim Übersetzen bemängelt wird), so seh ich es wie Sascha: es ist sinnfrei, darüber weiter zu diskutieren.

Nein, ich hatte nicht schon mitbekommen, dass die obige Definition nur ein erster Wurf ist. Ich hielt es für die Beschreibung eines genutzt werdenden (wenn auch, wie im 2. Abschnitt mitgeteilt wird, umstrittenen) Testverfahrens. -/- Ich hatte gesagt, dass es ein Beispiel in Programmiersprache C ist, nicht in Java. In C ist "7;" ein NOP, aber dennoch (soweit mir bekannt) erlaubt. Also darf es auch in Produktionscode stehen (sofern Richtlinien nicht dagegen stehen, was hier nicht unser Thema ist). Die Entwicklungsabteilung könnte es für interne Zwecke nutzen, z. B. für irgendein obskures Quelltext-Analysetool BROWSE_HELPER, für das "7;" kein NOP sein mag. Sagen wir, das sei in der Firma erlaubt oder sogar gefordert. Sagen wir, in der Anforderungs-Dokumentation steht nichts (und zwar gewollt nichts, weil keinen Einfluss auf das Verhalten habend) zum Tool BROWSE_HELPER. So könnte es zu obigem Code gekommen sein. -/- All das ist aber völlig egal, ich kann gerne auch Produktionscode ohne "7;" zum Testen geben:
int sieben() {          return 5          ;          }
Kommt ihr jetzt endlich mit dem Testcode für den zugehörigen "100 % Testabdeckung"-Test aus der Deckung? -- Volker

Mir ist auch nicht klar, worauf du hinauswillst. Die Definition ist doch gerade in der Hinsicht Unfug, dass man z. B. Code zufügen kann, ohne dass der Test das merkt. Darum diskutieren wir doch überhaupt. Hast du mal in den Wikipedia-Link geschaut? Da ist noch ein Beispiel und eine m. E. bessere Definition. -- SDö

Ich komme nicht mehr mit. Du liest die Definition (diejenige in der ersten Zeile oben) anscheinend genau gegenteilig wie ich. Während du herausliest, "dass man z. B. Code zufügen kann, ohne dass der Test das merkt", lese ich heraus, dass man z. B. keinen Code zufügen kann, ohne dass der Test das merkt (und fehl schlägt). -/- Der Wikipedia-Artikel bereitet mir kein Problem, da geht es um sattsam bekannte Dinge, und nicht, wie hier, um Tests, die fehl schlagen, wenn eine Änderung am Produktionscode durchgeführt wird. (Und zu so einem Test hätte ich gerne mal den Testcode gesehen.) -- Volker

Sorry, wir sind offenbar völlig einer Meinung. Ich präzisiere nochmal: Man kann immer Code zufügen, ohne dass ein Runtime-Test das merkt. Es ist also nicht möglich, Tests zu schreiben, die 100% Codeabdeckung im obigen Sinne liefern, ohne auf statische Analyse zurückzugreifen. Mit statischer Analyse ist es wiederum einfach, das ganze ad absurdum zu führen, indem man einfach den alten Quellcode mit dem neuen Quellcode vergleicht. Allein aus diesem Grund halte ich die Definition für fragwürdig. In der Wikipedia steht außerdem, dass schon die Ermittlung aller Ausführungspfade in einem Programm NP-schwierig ist. Wer da 100% erreicht, kann also mal locker mit sich zufrieden sein. ;-)

Das wollte ich hören (und es nicht zuerst sagen, weil ich noch glaubte, es nicht begriffen zu haben), ich verstehe das oben beschriebene Testverfahren nämlich ebenfalls als (z. B.) ein Vergleichen des vormals beiseite gelegten Programmcodes mit dem akuten Programcode. Gibt es bei dem Vergleich (mindestens) einen Unterscheid, scheitert der Test. Das ist vom Testverfahren so gewollt, d. h. ein derartiges Scheitern ist kein Zeichen für einen falsch kodierten Testfall, sondern ein Zeichen für fehlerhaften Programmcode (hier: veränderten Programmcode). D. h., dass in diesem Fall der Programmcode korrigiert werden (hier: der ursprüngliche Programmcode wieder hergestellt werden) muss. -/- Ein recht spaßiges Verfahren mit vermutlich ca. Nullrelevanz. -- Volker


KategorieTesten
StartSeite | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Text dieser Seite ändern (zuletzt geändert: 2. August 2004 14:45 (diff))
Suchbegriff: gesucht wird
im Titel
im Text