Jetzt weiß ich, dass die Leute diese Frage doppelt oder oft in Betracht ziehen könnten. In diesem Fall würde ich mich über einen Link zu relevanten Fragen mit Antwort auf meine Frage freuen.
Ich war kürzlich mit einigen Leuten über die Codeabdeckung nicht einverstanden. Ich habe eine Gruppe von Leuten, die möchten, dass unser Team sich nicht mehr mit der Codeabdeckung befasst, basierend auf dem Argument, dass 100% Abdeckung keine Tests mit guter Qualität und damit Code mit guter Qualität bedeutet.
Ich konnte zurückschieben, indem ich das Argument verkaufte, dass Code Coverage mir sagt, was nicht sicher getestet wurde, und uns dabei helfen, uns auf diese Bereiche zu konzentrieren.
(Das Obige wurde in ähnlicher Weise in anderen SO-Fragen wie dieser diskutiert - /programming/695811/pitfalls-of-code-coverage )
Das Argument dieser Leute ist - dann würde das Team schnell Tests mit geringer Qualität erstellen und damit Zeit verschwenden, ohne signifikante Qualität hinzuzufügen.
Obwohl ich ihren Standpunkt verstehe, suche ich nach einer Möglichkeit, die Codeabdeckung robuster zu machen, indem ich robustere Tools / Frameworks einführe , die mehr Abdeckungskriterien berücksichtigen(Functional, Statement,Decision, Branch, Condition, State, LCSAJ, path, jump path, entry/exit, Loop, Parameter Value etc)
.
Was ich suche, ist ein Vorschlag für eine Kombination solcher Tools und Praktiken / Prozesse zur Codeabdeckung, die mir helfen können, solchen Argumenten entgegenzuwirken, während ich mich bei meiner Empfehlung wohl fühle.
Ich würde auch alle begleitenden Kommentare / Vorschläge begrüßen, die auf Ihren Erfahrungen / Kenntnissen darüber basieren, wie Sie einem solchen Argument entgegenwirken können, da die Codeabdeckung meinem Team zwar subjektiv, aber dabei geholfen hat, sich der Codequalität und des Werts von Tests bewusster zu werden.
Bearbeiten: Um Verwirrung über mein Verständnis der Schwäche der typischen Codeabdeckung zu vermeiden, möchte ich darauf hinweisen, dass ich mich nicht auf Statement Coverage
Tools (oder Codezeilen, die ausgeführt werden) beziehe (es gibt viele). In der Tat ist hier ein guter Artikel über alles, was daran falsch ist: http://www.bullseye.com/statementCoverage.html
Ich suchte nach mehr als nur Aussage- oder Zeilenabdeckung und ging mehr auf mehrere Abdeckungskriterien und -stufen ein.
Siehe: http://en.wikipedia.org/wiki/Code_coverage#Coverage_criteria
Die Idee ist, dass, wenn ein Tool uns unsere Abdeckung anhand mehrerer Kriterien mitteilen kann, dies zu einer angemessenen automatisierten Bewertung der Testqualität wird. Ich versuche keineswegs zu sagen, dass die Leitungsabdeckung eine gute Einschätzung ist. In der Tat ist das die Voraussetzung meiner Frage.
Edit:
Ok, vielleicht habe ich es ein bisschen zu dramatisch projiziert, aber du verstehst, worum es geht. Das Problem besteht darin, Prozesse / Richtlinien im Allgemeinen in allen Teams auf homogene / konsistente Weise festzulegen. Und die Befürchtung ist allgemein, wie Sie die Qualität der Tests sicherstellen, wie Sie die garantierte Zeit zuweisen, ohne Maßnahmen zu ergreifen. Daher mag ich eine messbare Funktion, die es uns ermöglicht, die Codequalität zu verbessern, wenn wir sie mit geeigneten Prozessen und den richtigen Tools sichern, ohne zu wissen, dass Zeit nicht für verschwenderische Prozesse aufgewendet wird.
EDIT: Soweit ich aus den Antworten habe:
- Codeüberprüfungen sollten Tests abdecken, um die Qualität der Tests sicherzustellen
- Die Test First-Strategie hilft dabei, nachträglich geschriebene Tests zu vermeiden, um die Abdeckung einfach zu erhöhen.
- Erkundung alternativer Tools, die andere Testkriterien als nur Anweisung / Zeile abdecken
- Die Analyse des abgedeckten Codes / der Anzahl der gefundenen Fehler würde dazu beitragen, die Bedeutung der Abdeckung zu erkennen und einen besseren Fall zu finden
- Vertrauen Sie vor allem auf die Beiträge des Teams, um das Richtige zu tun und für ihre Überzeugungen zu kämpfen
- Abgedeckte Blöcke / Anzahl der Tests - Umstritten, enthält aber einen gewissen Wert
Vielen Dank für die tollen Antworten. Ich schätze sie wirklich. Dieser Thread ist besser als stundenlanges Brainstorming mit den vorhandenen Kräften.
quelle
Antworten:
Nach meiner Erfahrung ist die Codeabdeckung genauso nützlich, wie Sie es machen . Wenn Sie gute Tests schreiben , die alle Ihre Fälle abdecken, bedeutet das Bestehen dieser Tests, dass Sie Ihre Anforderungen erfüllt haben. In der Tat , dass die ist genau Idee , dass Test - Driven Development Anwendungen. Sie schreiben die Tests vor dem Code, ohne etwas über die Implementierung zu wissen (manchmal bedeutet dies, dass ein anderes Team die Tests vollständig schreibt). Diese Tests werden eingerichtet, um zu überprüfen, ob das Endprodukt alles tut, was Ihre Spezifikationen vorgeben, und DANN schreiben Sie den Mindestcode, um diese Tests zu bestehen.
Das Problem hierbei ist natürlich, dass Sie, wenn Ihre Tests nicht stark genug sind, Randfälle oder unvorhergesehene Probleme übersehen und Code schreiben, der Ihren Spezifikationen nicht wirklich entspricht. Wenn Sie wirklich Tests verwenden möchten, um Ihren Code zu überprüfen, ist das Schreiben guter Tests eine absolute Notwendigkeit, oder Sie verschwenden wirklich Ihre Zeit.
Ich wollte die Antwort hier bearbeiten, da mir klar wurde, dass Ihre Frage nicht wirklich beantwortet wurde. Ich würde mir diesen Wiki-Artikel ansehen, um einige der angegebenen Vorteile von TDD zu sehen. Es kommt wirklich darauf an, wie Ihre Organisation am besten funktioniert, aber TDD wird definitiv in der Branche verwendet.
quelle
Statement Coverage
(oder ausgeführte Codezeilen). Ich war auf der Suche nach mehr als nur Aussage oder Zeilenabdeckung, mehr inmultiple coverage criteria
und Ebenen. Siehe: en.wikipedia.org/wiki/Code_coverage#Coverage_criteria und en.wikipedia.org/wiki/Linear_Code_Sequence_and_Jump . Die Idee ist, dass, wenn ein Tool uns unsere Abdeckung anhand mehrerer Kriterien mitteilen kann, dies zu einer angemessenen automatisierten Bewertung der Testqualität wird. Ich versuche keineswegs zu sagen, dass die Leitungsabdeckung eine gute Einschätzung ist. In der Tat ist das die Voraussetzung meiner Frage.Zunächst einmal, die Menschen tun Anwalt 100% Deckung:
Steve McConnell, Code Complete , Kapitel 22: Entwicklertests.
Wie Sie und andere bereits erwähnt haben, wird die Codeabdeckung allein aus Gründen der Abdeckung wahrscheinlich nicht viel bewirken. Aber wenn Sie eine Codezeile nicht ausführen können, warum wird sie geschrieben?
Ich würde vorschlagen, das Argument zu lösen, indem Sie Daten zu Ihren eigenen Projekten sammeln und analysieren.
Um die Daten zu sammeln, verwende ich persönlich die folgenden Tools:
Sobald Sie dies (oder etwas Ähnliches) eingerichtet haben, können Sie beginnen, Ihre eigenen Daten genauer zu betrachten:
Ich würde erwarten , dass Ihre Daten werden Ihre Position auf Codeabdeckung unterstützen; Das war sicherlich meine Erfahrung. Wenn dies jedoch nicht der Fall ist, kann Ihre Organisation möglicherweise mit niedrigeren Standards für die Codeabdeckung erfolgreich sein, als Sie möchten. Oder vielleicht sind deine Tests nicht sehr gut. Die Aufgabe wird sich hoffentlich darauf konzentrieren, Software mit weniger Fehlern zu erstellen, unabhängig von der Lösung der Uneinigkeit über die Codeabdeckung.
quelle
Dies ist eine Vertrauensfrage , keine Tools .
Fragen Sie sie, warum sie, wenn sie dieser Aussage wirklich glauben, dem Team vertrauen würden, überhaupt Code zu schreiben?
quelle
Ich denke das ist das Problem. Entwickler interessieren sich nicht (und oft aus hervorragenden Gründen) für konsistente oder globale Richtlinien und möchten die Freiheit, das zu tun, was sie für richtig halten, anstatt Unternehmensrichtlinien einzuhalten.
Dies ist sinnvoll, wenn Sie nicht nachweisen, dass globale Prozesse und Maßnahmen einen Wert haben und sich positiv auf Qualität und Entwicklungsgeschwindigkeit auswirken.
Übliche Zeitleiste:
quelle
Nach meiner Erfahrung gibt es einige Dinge, die mit der Codeabdeckung kombiniert werden müssen, damit sich die Metrik lohnt:
Codeüberprüfungen
Wenn Sie schlechte Tests an den Entwickler zurücksenden können, kann dies dazu beitragen, die Anzahl der schlechten Tests zu begrenzen, die diese bedeutungslose Abdeckung bieten.
Bug-Tracking
Wenn ein Modul eine Reihe von Codeabdeckungen aufweist, in diesem Bereich jedoch immer noch viele / schwerwiegende Fehler auftreten, weist dies möglicherweise auf ein Problem hin, bei dem der Entwickler bei seinen Tests Verbesserungen benötigt.
Pragmatismus
Niemand wird mit guten Tests auf nicht trivialem Code zu 100% kommen. Wenn Sie als Teamleiter die Codeabdeckung betrachten, aber anstatt zu sagen "Wir müssen N% erreichen!" Sie identifizieren Lücken und fordern die Leute auf, "die Abdeckung in Modul X zu verbessern", um Ihr Ziel zu erreichen, ohne den Leuten die Möglichkeit zu geben, das System zu spielen.
Abgedeckte Blöcke / Anzahl der Tests
Die meisten Tools zur Codeabdeckung listen die abgedeckten Blöcke im Vergleich zu den nicht abgedeckten Blöcken auf. Wenn Sie dies mit der Anzahl der tatsächlichen Tests kombinieren, erhalten Sie eine Metrik, die angibt, wie umfassend die Tests sind, entweder schlechte Tests oder gekoppeltes Design. Dies ist nützlicher als ein Delta von einem Sprint zum anderen, aber die Idee ist dieselbe - kombinieren Sie die Codeabdeckung mit anderen Metriken, um mehr Einblick zu erhalten.
quelle
Hier sind meine 2 Cent.
Es gibt viele Praktiken, die in letzter Zeit viel Aufmerksamkeit erhalten haben, weil sie Vorteile für die Softwareentwicklung bringen können. Einige Entwickler wenden diese Praktiken jedoch blind an: Sie sind überzeugt, dass das Anwenden einer Methodik dem Ausführen eines Algorithmus gleicht und dass man nach dem Ausführen der richtigen Schritte das gewünschte Ergebnis erzielen sollte.
Einige Beispiele:
Ich denke, das Grundproblem bei den obigen Aussagen ist, dass Menschen keine Computer sind und das Schreiben von Software nicht mit dem Ausführen eines Algorithmus vergleichbar ist.
Die obigen Aussagen enthalten also einige Wahrheiten, vereinfachen die Dinge jedoch etwas zu sehr, z.
Zurück zur Codeabdeckung.
Ich denke, Sie müssen von Fall zu Fall beurteilen, ob es sich lohnt, ein bestimmtes Modul zu 100% abzudecken.
Führt das Modul einige sehr wichtige und komplizierte Berechnungen durch? Dann möchte ich jede einzelne Codezeile testen, aber auch aussagekräftige Unit-Tests schreiben (Unit-Tests, die in diesem Bereich sinnvoll sind).
Führt das Modul eine wichtige, aber einfache Aufgabe aus, z. B. das Öffnen eines Hilfefensters beim Klicken auf eine Schaltfläche? Ein manueller Test wird wahrscheinlich effektiver sein.
Meiner Meinung nach haben sie Recht: Sie können die Codequalität nicht durchsetzen, indem Sie nur eine 100% ige Codeabdeckung benötigen. Das Hinzufügen weiterer Tools zum Berechnen der Abdeckung und zum Erstellen von Statistiken hilft ebenfalls nicht. Sie sollten vielmehr diskutieren, welche Teile des Codes empfindlicher sind und ausführlich getestet werden sollten und welche weniger fehleranfällig sind (in dem Sinne, dass ein Fehler ohne Verwendung von Komponententests viel einfacher entdeckt und behoben werden kann).
Wenn Sie den Entwicklern eine 100% ige Codeabdeckung auferlegen, beginnen einige, alberne Komponententests zu schreiben, um ihren Verpflichtungen nachzukommen, anstatt zu versuchen, vernünftige Tests zu schreiben.
Vielleicht ist es eine Illusion, dass Sie die menschliche Intelligenz und das Urteilsvermögen messen können. Wenn Sie kompetente Kollegen haben und deren Urteilsvermögen vertrauen, können Sie akzeptieren, wenn sie Ihnen sagen, dass "für dieses Modul eine Erhöhung der Codeabdeckung nur einen geringen Nutzen bringt. Lassen Sie uns also keine Zeit damit verbringen" oder "für dieses Modul, das wir benötigen." So viel Berichterstattung wir bekommen können, brauchen wir eine zusätzliche Woche, um sinnvolle Unit-Tests durchzuführen. "
Also (wieder sind dies meine 2 Cent): Versuchen Sie nicht, einen Prozess zu finden und Parameter wie die Codeabdeckung festzulegen, die für alle Teams, für alle Projekte und für alle Module geeignet sein müssen. Einen solchen allgemeinen Prozess zu finden, ist eine Illusion, und ich glaube, wenn Sie einen gefunden haben, wird er suboptimal sein.
quelle
"Das Team würde darauf reagieren, indem es schnell Tests mit geringer Qualität erstellt und damit Zeit verschwendet, ohne signifikante Qualität hinzuzufügen."
Dies ist ein echtes Risiko, nicht nur theoretisch.
Code-Überalterung allein ist eine dysfunktionale Metrik. Ich habe diese Lektion auf die harte Tour gelernt. Einmal habe ich es ohne die Verfügbarkeit von Ausgleichsmetriken oder -praktiken hervorgehoben. Hunderte von Tests, die Ausnahmen abfangen und maskieren, und ohne Behauptungen, sind eine hässliche Sache.
"Vorschlag für eine Kombination solcher Tools zur Codeabdeckung und der dazugehörigen Praktiken / Prozesse"
Zusätzlich zu allen anderen Vorschlägen gibt es eine Automatisierungstechnik, mit der die Qualität von Tests bewertet werden kann: Mutationstests ( http://en.wikipedia.org/wiki/Mutation_testing ). Für Java-Code funktioniert PIT ( http://pitest.org/ ) und es ist das erste Mutationstest-Tool, auf das ich gestoßen bin.
Wie Sie bemerken, ist eine mangelnde Codeabdeckung leicht als Softwarequalitätsrisiko zu erkennen. Ich lehre, dass die Codeabdeckung eine notwendige, aber unzureichende Bedingung für die Softwarequalität ist. Wir müssen einen Balanced Scorecard-Ansatz verfolgen, um die Softwarequalität zu verwalten.
quelle
Die Codeabdeckung ist sicherlich kein Beweis für gute Komponententests, da sie korrekt sind.
Aber wenn sie nicht beweisen können, dass alle Unit-Tests gut sind (für welche Definition von Gut sie auch immer kommen können), ist dies wirklich ein stummer Punkt.
quelle
Ich habe immer festgestellt, dass die Codeabdeckung leicht für den Hawthorne-Effekt anfällig ist . Dies veranlasste mich zu der Frage: "Warum haben wir überhaupt Software-Metriken?" und die Antwort besteht normalerweise darin, ein umfassendes Verständnis des aktuellen Projektstatus zu vermitteln, z. B.:
"Wie nah sind wir dran?"
"Wie ist die Qualität dieses Systems?"
"Wie kompliziert sind diese Module?"
Leider wird es nie eine einzige Metrik geben, die Ihnen sagen kann, wie gut oder schlecht das Projekt ist, und jeder Versuch, diese Bedeutung aus einer einzelnen Zahl abzuleiten, wird sich zwangsläufig zu stark vereinfachen. Während es bei Metriken ausschließlich um Daten geht, ist die Interpretation ihrer Bedeutung eine viel emotionalere / psychologischere Aufgabe und kann daher wahrscheinlich nicht generisch auf Teams unterschiedlicher Zusammensetzung oder Probleme unterschiedlicher Domänen angewendet werden.
Im Falle der Berichterstattung wird sie meiner Meinung nach häufig als Proxy für die Codequalität verwendet, albiet als grobe. Das eigentliche Problem besteht darin, dass ein furchtbar kompliziertes Thema auf eine einzige Ganzzahl zwischen 0 und 100 reduziert wird, die natürlich verwendet wird, um potenziell nicht hilfreiche Arbeit in einer endlosen Suche nach einer 100% igen Abdeckung voranzutreiben. Leute wie Bob Martin werden sagen, dass 100% Deckung das einzige ernsthafte Ziel ist, und ich kann verstehen, warum das so ist, weil alles andere einfach willkürlich erscheint.
Natürlich gibt es viele Möglichkeiten, eine Abdeckung zu erhalten, die mir nicht wirklich hilft, die Codebasis zu verstehen - z. B. ist es wertvoll, toString () zu testen? Was ist mit Gettern und Setzern für unveränderliche Objekte? Ein Team hat nur so viel Aufwand, um sich in einer festgelegten Zeit zu bewerben, und diese Zeit scheint immer kürzer zu sein als die Zeit, die für eine perfekte Arbeit erforderlich ist. In Ermangelung eines perfekten Zeitplans müssen wir uns also mit Annäherungen begnügen.
Eine Metrik, die ich für gute Annäherungen als nützlich befunden habe, ist Crap4J . Es ist jetzt nicht mehr verfügbar, aber Sie können es problemlos selbst portieren / implementieren. Crap4J versucht, die Codeabdeckung mit der zyklomatischen Komplexität in Beziehung zu setzen, indem impliziert wird, dass der kompliziertere Code (ifs, whiles, fors usw.) eine höhere Testabdeckung aufweisen sollte. Für mich stimmte diese einfache Idee wirklich. Ich möchte verstehen, wo in meiner Codebasis ein Risiko besteht, und ein wirklich wichtiges Risiko ist die Komplexität. Mit diesem Tool kann ich schnell beurteilen, wie riskant meine Codebasis ist. Wenn es kompliziert ist, sollte die Abdeckung besser steigen. Wenn dies nicht der Fall ist, muss ich keine Zeit damit verschwenden, jede Codezeile abzudecken.
Dies ist natürlich nur eine Metrik und YMMV. Sie müssen Zeit damit verbringen, um zu verstehen, ob es für Sie sinnvoll ist und ob es Ihrem Team ein vernünftiges Gefühl dafür gibt, wo sich das Projekt befindet.
quelle
Ich würde nicht sagen, dass es der beste Weg ist, zurück zu gehen und vorhandenen Code abzudecken. Ich würde argumentieren, dass es sinnvoll ist, Deckungstests für jeden neuen Code, den Sie schreiben, oder für jeden Code, den Sie ändern, zu schreiben.
Wenn Fehler gefunden werden, schreiben Sie einen Test, der aufgrund dieses Fehlers fehlschlägt, und beheben Sie den Fehler, sodass der Test grün wird. Geben Sie in den Kommentaren des Tests ein, für welchen Fehler er geschrieben wurde.
Ziel ist es, genügend Vertrauen in Ihre Tests zu haben, damit Sie Änderungen vornehmen können, ohne auf unerwartete Nebenwirkungen achten zu müssen. Eine effektive Zusammenfassung der Ansätze zur Zähmung von nicht getestetem Code finden Sie unter Effektiv mit Legacy-Code arbeiten.
quelle