Wie viel Code Coverage ist "genug"?

37

Wir beginnen hier bei meiner Arbeit mit dem Streben nach Codeabdeckung, und ich muss nachdenken ... Wie viel Codeabdeckung reicht aus?

Wann kommen Sie an den Punkt, an dem die Renditen für die Codeabdeckung sinken? Was ist der Sweet Spot zwischen guter Berichterstattung und zu wenig? Variiert es je nach Art des Projekts, das Sie durchführen (z. B. WPF, WCF, Mobile, ASP.NET) (Dies sind C # -Klassen, die wir schreiben.)

Vaccano
quelle
Es gibt wirklich keine gute Antwort darauf; " Wie viel Unit-Test-Abdeckung benötigen Sie? " In den Artima Developer-Foren enthält einige hilfreiche Ratschläge.
RN01

Antworten:

19

Wir streben mindestens 70% an. Bei Dingen, die leichter zu testen sind (zum Beispiel funktionale Datenstrukturen), streben wir 90% an und die meisten Menschen streben so nahe wie möglich an 100%. Bei WPF-bezogenen Dingen und anderen Frameworks, die sehr schwer zu testen sind, erhalten wir eine viel geringere Abdeckung (kaum 70%).

Noah Richards
quelle
Ist WPF von Natur aus schwer zu testen, oder haben Sie sich noch nicht die Mühe gemacht, die beste Strategie für eine bessere Abdeckung auszuarbeiten?
JBRWilkinson
Ein Großteil davon rührt von der Tatsache her, dass WPF-Eingaben schwer zu fälschen sind. Unsere Tests sind so Unit-Y oder API-Y, wie wir es bekommen können, und die Unfähigkeit, die Ebene, die "über" WPF liegt (zumindest Eingabe), leicht zu fälschen, erschwert das Testen. Dies ist kein großes Problem, da die Teile der API, die keine grafische Benutzeroberfläche sind, einfach zu testen sind. Es ist jedoch nur der letzte Abschnitt, der von unserem Modell (oder Ansichtsmodell) zu WPF führt, der eine Herausforderung darstellt.
Noah Richards
1
Ja, WPF ist eine Hündin zum Testen. Und ich könnte damit leben, wenn es Kompilierungszeit gäbe, um die Bindungen in den Ansichten zu überprüfen. Zumindest würde der Build unterbrochen, wenn Sie eine Eigenschaft ändern, an die die Ansicht gebunden ist. Aber das tut es nicht. Das hat uns veranlasst, GUI-Automatisierung in unseren Abnahmetests zu verwenden, was auch eine Hündin zum Schreiben ist. Zumindest gibt es uns aber Zuversicht, dass das System funktioniert.
Pete
Ich mag die Nummer (70%). Wenn meine Teams größer werden, finde ich in der Regel Tests für die Abdeckung als für den Wert. In Bezug auf den WPF-Kommentar stehen wir erst am Anfang. Das heißt, wir bauen / strukturieren WPF-Code nicht so, dass er leicht zu testen ist. Scheinmodelle helfen. Entwerfen Sie den Code so, dass er testbar ist. Und ja, an dieser Stelle gibt es nur wenige Beispiele, so dass Sie darüber nachdenken müssen. Nicht anders als bei den meisten Entwicklern, als TDD zum ersten Mal eingeführt wurde, nur mit weniger Branchenerfahrung.
Jim Rush
Um genauer zu sein, WPF ist ein Bitch-to- Unit- Test. Wenn Sie aus irgendeinem Grund eine größere Abdeckung benötigen, können Sie die Abdeckung von WPF-Klassen am einfachsten mit codierten UI-Tests / Integrationstests
jk
55

Ich bin der Meinung, dass Code-Coverage allein eine schlechte Metrik ist. Es ist einfach, Tonnen unnützer Tests zu erstellen, die den Code abdecken , aber die Ausgabe nicht ausreichend überprüfen oder beispielsweise keine Edge-Cases testen. Code abzudecken bedeutet nur, dass es keine Ausnahme auslöst, nicht, dass es richtig ist. Sie brauchen Qualitätstests - die Menge ist nicht so wichtig.

Fischtoaster
quelle
8
Code Coverage sollte eine der Ausgaben Ihrer automatisierten Tests sein, die in Ihrem automatisierten Build-System durchgeführt werden. Tests, die die Ausgabe nicht überprüfen, sind kaum wert. Unter dem Schwellenwert liegende Abdeckung weist auf neue Funktionen mit keinen oder unzureichenden Tests hin. Es sollte nicht etwas sein, mit dem man die Leute verprügeln kann - aber es kann sicherlich ungetesteten Code anzeigen.
JBRWilkinson
3
Ich bin der zweite JBRWilkinson hier, obwohl dies kein Indikator für guten Code ist. Die Codeabdeckung kann ein Indikator für fehlende Tests sein. Ihre Komponententests können übrigens auch andere Metriken liefern, wie z. B. Leistungsmessungen, sodass Sie nicht plötzlich überrascht sind, wenn eine neue Version unter der unerwarteten Arbeitslast auf dem Server abstürzt.
Matthieu M.
4
Ich halte das für eine falsche Wahl. Qualitativ hochwertige Tests, die nur eine geringe Menge an Code berühren, sind insgesamt schlechte Qualitätsmaßstäbe, ebenso wie "Tests", die eine große Menge an Code berühren, aber die Ergebnisse nicht wirklich überprüfen. Stellen Sie sich einen Qualitätssicherungsprozess für Autos vor, bei dem das Vorderrad auf der Fahrerseite gründlich getestet wurde, aber kein anderer Teil des Autos. Das wäre genauso schlimm wie ein Qualitätssicherungsprozess, bei dem nur ein Mann das ganze Auto mustert und sagt: "Ja, sieht gut aus."
Noah Richards
38

"Genug" ist, wenn Sie Ihren Code mit der Gewissheit ändern können, dass Sie nichts kaputt machen. Bei einigen Projekten sind dies möglicherweise 10%, bei anderen 95%.

Es ist fast nie so hoch wie 100%. Manchmal kann der Versuch, eine 100% ige Codeabdeckung zu erzielen, jedoch eine gute Möglichkeit sein, Cruft von der Codebasis zu entfernen. Vergessen Sie nicht, dass es zwei Möglichkeiten gibt, die Codeabdeckung zu erhöhen: Schreiben Sie mehr Tests oder nehmen Sie Code heraus. Wenn Code nicht behandelt wird, weil er schwer zu testen ist, besteht eine gute Chance, dass Sie ihn vereinfachen oder überarbeiten können, um ihn einfacher zu testen. Wenn es zu dunkel ist, um es zu testen, besteht normalerweise eine gute Chance, dass nichts anderes im Code es verwendet.

RevBingo
quelle
24
"Testen, bis aus Angst Langeweile wird"
Brad Mace
2
Positiv zu dem Kommentar zum Entfernen von Code. Ich verwende dafür die ganze Zeit Kennzahlen zur Codeabdeckung (in VS werden die nicht abgedeckten Zeilen hervorgehoben).
Noah Richards
Tolles Zitat @bemace
jayraynet
14

Die Codeabdeckung nähert sich zu 100% asymptotisch. Folglich sind die letzten 5% wahrscheinlich mehr Aufwand als es wert ist, da Sie anfangen, für den aufgewendeten Aufwand verschwindend geringe Erträge zu erzielen.

Robert Harvey
quelle
7

Coverage ist eine Metrik, die im Auge behalten werden muss, aber nicht das ultimative Ziel sein sollte. Ich habe schon viel Code mit hoher Abdeckung gesehen (und zugegebenermaßen geschrieben!) - 100% Abdeckung (TDD natürlich):

  • Wanzen kommen noch auf
  • Design kann immer noch schlecht sein
  • Sie können sich wirklich selbst töten, indem Sie für ein beliebiges Abdeckungsziel schießen - wählen Sie Ihre Schlachten aus: p

Es gibt einen "The Way of Testivus" -Eintrag , auf den ich hier verweisen möchte :)

HY
quelle
5

Nur 20% der meisten Codes werden in 80% der Fälle ausgeführt . Eine Codeabdeckungsanalyse ist nur dann sehr nützlich, wenn sie mit einem Anrufdiagramm kombiniert wird , um zu bestimmen, was am meisten getestet werden muss. Das sagt Ihnen, wo Ihre Randfälle wahrscheinlich sind. Sie können 100 Tests nur für die Randfälle erstellen, die weniger als 5% des tatsächlichen Codes ausmachen.

Vergewissern Sie sich also, dass Sie 100% der 20%, die kritische Pfade definieren, und mindestens 50% der übrigen Pfade abdecken (gemäß dem Aufrufdiagramm). Dies sollte (ungefähr) 70% - 75% der Gesamtabdeckung ergeben, variiert jedoch.

Verbrennen Sie keine Zeit und versuchen Sie nicht, eine Gesamtabdeckung von über 70% zu erreichen, ohne kritische Randfälle zu überprüfen.

Tim Post
quelle
Generieren Codeabdeckungstools nicht per Definition ein Anrufdiagramm?
JBRWilkinson
4

Verwenden Sie die Abdeckung als Richtlinie, um Bereiche anzugeben, die nicht getestet wurden. Anstatt ein Deckungsmandat zu haben, ist es klüger, den Grund für den nicht abgedeckten Code zu verstehen. Ein Grund für das Defizit ist eine gute Disziplin, mit der sich die Risiken ausgleichen lassen.

Manchmal ist der Grund weniger wünschenswert als "z. B. keine Zeit mehr", für eine vorzeitige Veröffentlichung ist er jedoch in Ordnung. Es ist besser, Bereiche zu markieren, in die Sie später zurückkehren können, um die Abdeckung zu verbessern.

Ich arbeite an kritischer Flugsoftware, bei der eine 100% ige Kontoauszugsdeckung für nicht kritische Systeme als geeignet angesehen wird. Für die kritischeren Systeme prüfen wir die Abdeckung von Zweigen / Entscheidungen und verwenden eine Technik namens MC / DC, die manchmal nicht streng genug ist.

Wir müssen auch sicherstellen, dass wir auch den Objektcode abgedeckt haben.

Es ist ein Gleichgewicht zwischen Risiko, in unserem Fall sehr hoch, und Wert / Kosten. Eine fundierte Auswahl ist erforderlich, da das Risiko besteht, dass ein Fehler übersehen wird.

Mark Fisher
quelle
3

Wenn Sie Änderungen in Betracht ziehen, die sich auf die Laufzeitleistung, die Sicherheit, die Flexibilität oder die Wartbarkeit auswirken, um mehr Code-Abdeckung zu ermöglichen, ist es Zeit, die Suche nach mehr Code-Abdeckung zu beenden.

Ich habe Projekte, bei denen dieser Punkt 0% beträgt, weil die Abdeckung nicht berechnet werden kann, ohne das Design zu beeinträchtigen, und andere Projekte, bei denen dieser Wert 92% beträgt.

Kennzahlen zur Codeabdeckung sind nur hilfreich, um darauf hinzuweisen, dass Sie möglicherweise einige Tests verpasst haben. Sie sagen Ihnen nichts über die Qualität Ihrer Tests.

Rechnung
quelle
2

Platzkritische Software erfordert eine 100% ige Abdeckung der Kontoauszüge.

Zunächst macht es keinen Sinn. Jeder weiß, dass eine vollständige Testabdeckung nicht bedeutet, dass der Code vollständig getestet wurde und dass es nicht so schwierig ist, eine 100% ige Abdeckung zu erhalten, ohne die Anwendung tatsächlich zu testen.

Trotzdem ist 100% Deckung eine Untergrenze: Obwohl 100% Deckung kein Beweis für eine fehlerfreie Software ist, ist es sicher, dass der Code bei einer geringeren Deckung nicht vollständig getestet wird und dies für platzkritische Software einfach nicht akzeptabel ist.

mouviciel
quelle
2

Ich mag die Antwort von @ RevBingo wirklich, weil er vorschlägt, dass der Kampf um 100% dazu führen kann, dass Sie nicht verwendeten Code bereinigen oder löschen. Was ich in den anderen Antworten nicht gesehen habe, ist ein Gefühl dafür, wann Sie eine hohe Abdeckung benötigen und wann nicht. Ich habe versucht, damit anzufangen. Ich denke, das Hinzufügen von Details zu einem Diagramm wie diesem wäre nützlicher, als eine Testabdeckungsnummer zu finden, die für den gesamten Code richtig ist.

100%

Für eine öffentliche API wie die java.util-Sammlungen, die nicht an eine Datenbank gekoppelt ist und kein HTML zurückgibt, halte ich 100% ige Abdeckung für ein vorrangiges Startziel, selbst wenn Sie sich aus Zeitgründen mit 90-95% zufrieden geben Einschränkungen. Das Erhöhen der Testabdeckung nach Abschluss des Features führt zu einer genaueren Überprüfung als andere Arten der Codeüberprüfung. Wenn Ihre API überhaupt populär ist, werden die Leute sie in einer Weise verwenden, in eine Unterklasse unterteilen, deserialisieren usw., die Sie nicht erwarten können. Sie möchten nicht, dass ihre erste Erfahrung darin besteht, einen Fehler zu finden oder ein Versehen beim Entwerfen!

90%

Für Geschäftsinfrastrukturcode, der Datenstrukturen aufnimmt und Datenstrukturen zurückgibt, ist 100% wahrscheinlich immer noch ein gutes Startziel, aber wenn dieser Code nicht öffentlich genug ist, um viel Missbrauch auszulösen, sind 85% vielleicht noch akzeptabel?

75%

Für Code, der Strings aufnimmt und zurückgibt, halte ich Unit-Tests für viel brüchiger, kann aber in vielen Situationen dennoch nützlich sein.

50% oder weniger

Ich hasse es, Tests für Funktionen zu schreiben, die HTML zurückgeben, weil es so spröde ist. Was ist, wenn jemand das CSS, das JavaScript oder das gesamte von Ihnen zurückgegebene HTML und Englisch ändert, was für den menschlichen Endbenutzer keinen Sinn ergibt? Wenn Sie eine Funktion finden, die viel Geschäftslogik verwendet, um ein wenig HTML zu erzeugen, ist dies möglicherweise einen Test wert. Aber die umgekehrte Situation ist möglicherweise überhaupt nicht prüfenswert.

In der Nähe von 0%

Für einige Codes lautet die Definition von "richtig" "für den Endbenutzer sinnvoll". Es gibt nicht-traditionelle Tests, die Sie mit diesem Code durchführen können, z. B. die automatische Grammatikprüfung oder die HTML-Validierung der Ausgabe. Ich habe sogar grep-Anweisungen für kleine Inkonsistenzen eingerichtet, denen wir bei der Arbeit häufig zum Opfer fallen, z. B. "Anmelden", wenn der Rest des Systems dies als "Anmelden" bezeichnet. Dieser Mann ist nicht unbedingt ein Komponententest, sondern eine hilfreiche Methode, um Probleme zu erkennen, ohne bestimmte Ergebnisse zu erwarten.

Letztendlich kann jedoch nur ein Mensch beurteilen, was für den Menschen sinnvoll ist. Unit Testing kann Ihnen da nicht weiterhelfen. Manchmal brauchen mehrere Menschen, um das genau zu beurteilen.

Absolut 0%

Dies ist eine traurige Kategorie, und ich fühle mich weniger als jemand, der sie schreibt. Aber in jedem ausreichend großen Projekt gibt es Hasenlöcher, die Wochen Zeit kosten können, ohne geschäftlichen Nutzen zu bringen.

Ich habe ein Buch gekauft, weil es angeblich zeigt, wie man Daten zum Testen von Hibernate automatisch verspottet. Es wurden jedoch nur Hibernate-HQL- und SQL-Abfragen getestet. Wenn Sie viel mit HQL und SQL arbeiten müssen, können Sie den Vorteil von Hibernate nicht wirklich nutzen. Es gibt eine Form der In-Memory-Datenbank für den Ruhezustand, aber ich habe nicht die Zeit investiert, um herauszufinden, wie man sie effektiv in Tests verwendet. Wenn ich das laufen lassen würde, würde ich eine hohe Testabdeckung (50% -100%) für jede Geschäftslogik haben wollen, die Sachen durch Navigieren in einem Objektdiagramm berechnet, wodurch Hibernate einige Abfragen ausführt. Meine Fähigkeit, diesen Code zu testen, liegt derzeit nahe bei 0%, und das ist ein Problem. Deshalb verbessere ich die Testabdeckung in anderen Bereichen des Projekts und versuche, reine Funktionen denen vorzuziehen, die auf die Datenbank zugreifen, vor allem, weil es einfacher ist, Tests für diese Funktionen zu schreiben. Immer noch,

GlenPeterson
quelle
1

Ich denke, es hängt von dem Teil der Anwendung ab, den Sie testen. ZB für Geschäftslogik oder jede Komponente, die komplexe Datenumwandlungen beinhaltet, würde ich eine Abdeckung von 90% (so hoch wie möglich) anstreben. Ich habe oft kleine, aber gefährliche Fehler gefunden, indem ich so viel Code wie möglich getestet habe. Ich würde solche Fehler lieber beim Testen finden, als sie ein Jahr später beim Kunden auftreten zu lassen. Ein Vorteil einer hohen Codeabdeckung ist auch, dass verhindert wird, dass Personen den Arbeitscode zu leicht ändern, da die Tests entsprechend angepasst werden müssen.

Andererseits denke ich, dass es Komponenten gibt, für die die Codeabdeckung weniger geeignet ist. Beispielsweise ist es beim Testen einer GUI sehr zeitaufwendig, einen Test zu schreiben, der den gesamten Code abdeckt, der beim Klicken auf eine Schaltfläche ausgeführt wird, um das Ereignis an die richtigen Komponenten zu senden. Ich denke, in diesem Fall ist es viel effektiver, den herkömmlichen Ansatz eines manuellen Tests zu verwenden, bei dem Sie einfach auf die Schaltfläche klicken und das Verhalten des Programms beobachten (öffnet sich das richtige Dialogfeld? Wird das richtige Tool ausgewählt?) ?).

Giorgio
quelle
0

Ich bin nicht der Meinung, dass die Verwendung der Codeabdeckung ein Maßstab dafür ist, ob Ihre Testsuite eine ausreichende Abdeckung aufweist.

Der Hauptgrund dafür ist, dass wenn Sie einen Prozess haben, bei dem Sie zuerst Code schreiben, dann einige Tests durchführen und dann anhand der Codeabdeckung feststellen, wo Sie einen Test verpasst haben, dieser Prozess verbessert werden muss. Wenn Sie echtes TDD machen, haben Sie eine Code-Abdeckung, die zu 100% sofort einsatzbereit ist (zugegebenermaßen gibt es einige Kleinigkeiten, auf die ich nicht teste). Wenn Sie sich jedoch die Codeabdeckung ansehen, um herauszufinden, was zu testen ist, werden Sie wahrscheinlich die falschen Tests schreiben.

Das Einzige, was Sie aus der Codeabdeckung schließen können, ist, dass Sie nicht genügend Tests haben, wenn sie zu niedrig ist. Aber wenn es hoch ist, gibt es keine Garantie, dass Sie alle richtigen Tests haben.

Pete
quelle