Ist es machbar, in umfangreichen JQuery / Backbonejs-Webanwendungen eine Codeabdeckung von 100% zu erwarten? Ist es sinnvoll, einen Sprint zu scheitern, weil die 100% ige Abdeckung nicht erreicht wird, wenn die tatsächliche Codeabdeckung in JavaScript / JQuery zwischen 92% und 95% liegt?
code-quality
tdd
bdd
Willz
quelle
quelle
Antworten:
Es ist ebenso realistisch wie unrealistisch.
Realistisch
Wenn Sie automatisierte Tests durchgeführt haben, von denen gezeigt wurde, dass sie die gesamte Codebasis abdecken, ist es angemessen, auf einer 100% igen Abdeckung zu bestehen.
Es hängt auch davon ab, wie kritisch das Projekt ist. Je kritischer, desto vernünftiger ist es, eine vollständige Codeabdeckung zu erwarten / zu fordern.
Dies ist einfacher für kleinere bis mittlere Projekte.
Unrealistisch
Sie beginnen mit einer Abdeckung von 0% ...
Das Projekt ist ungeheuerlich mit vielen, vielen Fehlerpfaden, die schwer wiederherzustellen oder auszulösen sind.
Das Management ist nicht bereit zu investieren, um sicherzustellen, dass die Abdeckung vorhanden ist.
Ich habe eine ganze Reihe von Projekten bearbeitet, die von keiner Berichterstattung bis zu anständigen reichen. Nie ein Projekt mit 100%, aber es gab sicherlich Zeiten, in denen ich mir wünschte, wir hätten eine bessere Abdeckung als 100%.
Letztendlich stellt sich die Frage, ob die vorhandene Abdeckung die erforderlichen Anforderungen erfüllt, damit das Team das Produkt problemlos versenden kann.
Wir kennen die Auswirkung eines Fehlers auf Ihr Projekt nicht und können daher nicht sagen, ob 92% oder 95% ausreichen oder ob diese 100% wirklich erforderlich sind. Oder Sie testen zu 100% alles, was Sie erwarten.
quelle
Wer testet die Tests?
Es ist bestenfalls sehr naiv und sogar im theoretischen Sinne unrealistisch und im geschäftlichen Sinne unpraktisch .
Das Testen jeder Codezeile ist kein gutes Ziel
Es ist sehr teuer, Tests zu schreiben, es ist Code, der selbst geschrieben und getestet werden muss, es ist Code, der in dem dokumentiert werden muss, was er tatsächlich zu testen versucht, es ist Code, der mit Änderungen der Geschäftslogik gepflegt werden muss und Die Tests schlagen fehl, weil sie veraltet sind. Das Verwalten automatisierter Tests und der dazugehörigen Dokumentation kann manchmal teurer sein als das Verwalten des Codes.
Dies soll nicht heißen, dass Komponententests und Integrationstests nicht nützlich sind, sondern nur dort, wo sie sinnvoll sind. Außerhalb von Branchen, die Menschen töten können, ist es nicht sinnvoll, jede Codezeile in einer Codebasis zu testen. Außerhalb dieser kritischen Tötung vieler Menschen ist es unmöglich, eine positive Kapitalrendite zu berechnen, die eine 100-prozentige Codeabdeckung mit sich bringen würde.
Halteproblem:
Da Sie nicht einmal beweisen können, dass etwas 100% funktioniert, warum machen Sie das zu Ihrem Ziel?
Schlicht und einfach, in den meisten Fällen ergibt es keinen geschäftlichen Sinn.
quelle
getXXX()/setXXX()
einfacher Zuweisungskonstruktoren für Wertobjekte eine gute Verwendung von Zeit und Ressourcen darstellt. Tut mir leid, dass dies in der Realität nicht der Fall ist, und eine äußerst naive Meinung, der es an praktischer Erfahrung mangelt, um dies zu sichern. Denken Sie daran, Testcode ist immer noch Code, der gepflegt werden muss. Je weniger Code Sie schreiben, um ein Problem zu lösen, desto besser ist es in jedem Fall .In den meisten Fällen bedeutet 100% Codeabdeckung, dass Sie ein wenig "betrogen" haben:
Grundsätzlich wurden die schwer zu testenden Teile in Bereiche verlagert, in denen sie nicht unbedingt als "Code" gelten. Es ist nicht immer realistisch, aber beachten Sie, dass all diese Methoden, unabhängig davon, wie Sie testen, die Arbeit an Ihrer Codebasis erleichtern.
quelle
Ein beeindruckendes Beispiel für eine 100% ige Zweigabdeckung in der Praxis finden Sie unter Testen von SQLite .
Ich realisiere, dass Ihre Frage speziell nach Javascript fragt, einem völlig anderen Typ von Softwareprodukt, aber ich möchte das Bewusstsein dafür wecken, was mit ausreichender Motivation getan werden kann.
quelle
Die 100% ige Code-Abdeckung für Unit-Tests für alle Teile einer bestimmten Anwendung ist auch bei neuen Projekten ein Traum. Ich wünschte, es wäre der Fall, aber manchmal kann man einfach keinen Code abdecken, egal wie sehr man versucht, externe Abhängigkeiten zu abstrahieren. Angenommen, Ihr Code muss einen Webdienst aufrufen. Sie können die Webservice-Aufrufe hinter einer Schnittstelle verbergen, um das Teil zu verspotten und die Geschäftslogik vor und nach dem Webservice zu testen. Die eigentliche Komponente, die zum Aufrufen des Webdienstes erforderlich ist, kann jedoch nicht einheitlich getestet werden (jedenfalls sehr gut). Ein weiteres Beispiel ist, wenn Sie eine Verbindung zu einem TCP-Server herstellen müssen. Sie können den Code verbergen, der eine Verbindung zu einem TCP-Server hinter einer Schnittstelle herstellt. Der Code, der eine physische Verbindung zu einem TCP-Server herstellt, kann jedoch nicht einheitlich getestet werden. Denn wenn es aus irgendeinem Grund nicht funktioniert, schlägt der Komponententest fehl. Und Komponententests sollten immer bestehen, egal wann sie aufgerufen werden.
Eine gute Faustregel ist, dass Ihre gesamte Geschäftslogik eine Codeabdeckung von 100% aufweisen sollte. Aber die Teile, die externe Komponenten aufrufen müssen, sollten möglichst 100% Codeabdeckung haben. Wenn Sie nicht erreichen können, würde ich es nicht zu viel schwitzen.
Viel wichtiger, sind die Tests korrekt? Entsprechen sie genau Ihrem Unternehmen und den Anforderungen? Codeabdeckung zu haben, nur um Codeabdeckung zu haben, bedeutet nichts, wenn Sie nur falsch testen oder falschen Code testen. Davon abgesehen ist eine Abdeckung von 92-95% hervorragend, wenn Ihre Tests gut sind.
quelle
unit testing
mit demintegration testing
Testen von Code, den Sie nicht geschrieben habenintegration
. Der TCP-Stack befindet sich in dem Betriebssystem, das Sie nicht testen sollten. Sie sollten davon ausgehen, dass es bereits von jemandem getestet wurde, der es geschrieben hat.Ich würde sagen, wenn der Code nicht mit dem spezifischen Ziel entworfen wurde, eine 100% ige Testabdeckung zu ermöglichen, sind 100% möglicherweise nicht erreichbar. Einer der Gründe wäre, dass Sie, wenn Sie defensiv codieren - was Sie sollten - manchmal Code haben sollten, der Situationen behandelt, von denen Sie sicher sind, dass sie aufgrund Ihrer Systemkenntnisse nicht auftreten oder nicht auftreten können. Es wäre per Definition sehr schwierig, solchen Code mit Tests abzudecken. Einen solchen Code nicht zu haben kann gefährlich sein - was ist, wenn Sie sich irren und diese Situation einmal von 256 vorkommt?? Was ist, wenn sich der Ort ohne Beziehung ändert, was Unmögliches möglich macht? So kann es sein, dass 100% mit "natürlichen" Mitteln ziemlich schwer zu erreichen sind - zB wenn Sie Code haben, der Speicher zuweist, und Sie haben Code, der überprüft, ob er fehlgeschlagen ist, es sei denn, Sie verspotten den Speichermanager (was möglicherweise nicht einfach ist). und schreiben Sie einen Test, der "out of memory" zurückgibt, der diesen Code möglicherweise schwer abdeckt. Für JS-Anwendungen kann es sich um eine defensive Codierung um mögliche DOM-Probleme in verschiedenen Browsern, mögliche Fehler bei externen Diensten usw. handeln.
Also würde ich sagen, man sollte sich bemühen, so nahe wie möglich an 100% zu sein und einen guten Grund für das Delta zu haben, aber ich würde nicht sehen, dass es nicht unbedingt scheitert, genau 100% zu bekommen. 95% können gut für ein großes Projekt sein, abhängig von den 5%.
quelle
Wenn Sie mit einem neuen Projekt beginnen und ausschließlich eine Test-First-Methode verwenden, ist eine Codeabdeckung von 100% in dem Sinne durchaus sinnvoll, dass der gesamte Code zu einem Zeitpunkt aufgerufen wird, zu dem Ihre Tests durchgeführt werden ausgeführt worden. Sie haben jedoch möglicherweise nicht jede einzelne Methode oder jeden einzelnen Algorithmus direkt getestet, da die Methoden sichtbar sind, und in einigen Fällen haben Sie möglicherweise einige Methoden nicht einmal indirekt getestet.
Das Testen Ihres Codes zu 100% ist möglicherweise eine kostspielige Aufgabe, insbesondere wenn Sie Ihr System nicht so entworfen haben, dass Sie dieses Ziel erreichen, und wenn Sie Ihre Konstruktionsanstrengungen auf Testbarkeit konzentrieren, schenken Sie wahrscheinlich nicht genug Aufmerksamkeit Ihre Anwendung so zu gestalten, dass sie den spezifischen Anforderungen entspricht, insbesondere wenn es sich um ein großes Projekt handelt. Es tut mir leid, aber Sie können es einfach nicht in beide Richtungen haben, ohne dass etwas kompromittiert wird.
Wenn Sie Tests in ein bestehendes Projekt einführen, in dem die Tests noch nicht gepflegt oder aufgenommen wurden, ist es unmöglich, eine 100-prozentige Codeabdeckung zu erzielen, ohne dass die Kosten für die Übung den Aufwand überwiegen. Das Beste, was Sie hoffen können, ist die Bereitstellung einer Testabdeckung für die wichtigsten Codeabschnitte, die als am häufigsten bezeichnet werden.
In den meisten Fällen würde ich sagen, dass Sie Ihren Sprint nur dann als "gescheitert" betrachten sollten, wenn Sie Ihre Ziele nicht erreicht haben. Eigentlich bevorzuge ich es, Sprints in solchen Fällen nicht als fehlgeschlagen zu betrachten, da Sie aus Sprints lernen müssen, die nicht den Erwartungen entsprechen, damit Ihre Planung beim nächsten Definieren eines Sprints richtig ist. Ungeachtet dessen halte ich es nicht für sinnvoll, die Codeabdeckung als einen Faktor für den relativen Erfolg eines Sprints zu betrachten. Ihr Ziel sollte es sein, gerade genug zu tun, damit alles wie angegeben funktioniert. Wenn Sie zuerst den Test programmieren, sollten Sie sich sicher sein können, dass Ihre Tests dieses Ziel unterstützen. Jeder zusätzliche Test, den Sie möglicherweise hinzufügen müssen, ist eine wirkungsvolle Zuckerbeschichtung und damit ein zusätzlicher Aufwand, der Sie daran hindern kann, Ihre Sprints zufriedenstellend abzuschließen.
quelle
Ich mache das nicht selbstverständlich, aber ich habe es bei zwei großen Projekten gemacht. Wenn Sie ohnehin ein Framework für Komponententests eingerichtet haben, ist es nicht schwer, aber es summiert sich zu einer Menge Tests.
Gibt es ein bestimmtes Hindernis, das Sie daran hindert, die letzten paar Zeilen zu treffen? Wenn nicht, ist es unkompliziert, eine Abdeckung von 95% auf 100% zu erreichen. Da du hier fragst, werde ich davon ausgehen , dass es ist etwas. Was ist das für etwas?
quelle
92% ist in Ordnung. Ich glaube, dass die wirklichen Fragen sind:
Ist 92% jetzt die "neue" Norm? Wenn der nächste Sprint 88% Tests hat, ist das in Ordnung? Dies ist häufig der Beginn der Aufgabe von Testsuiten.
Wie wichtig ist es, dass die Software funktioniert und keine Fehler aufweist. Sie haben Tests aus diesen Gründen, nicht "zum Testen"
Gibt es einen Plan zurück zu gehen und die fehlenden Tests auszufüllen?
Warum testen Sie? Es scheint, dass der Fokus auf% der abgedeckten Leitung und nicht auf der Funktionalität liegt
quelle
Martin Fowler schreibt in seinem Blog :
I would be suspicious of anything like 100% - it would smell of someone writing tests to make the coverage numbers happy, but not thinking about what they are doing.
Es gibt jedoch sogar Standards, die eine 100% ige Abdeckung auf Einheitenebene vorschreiben. Zum Beispiel ist es eine der Anforderungen in den Standards der Europäischen Raumfahrtgemeinschaft (ECSS, European Cooperation for Space Standardization). Das hier verlinkte Papier erzählt eine interessante Geschichte eines Projekts, das das Ziel hatte, eine 100% ige Testabdeckung in einer bereits fertig gestellten Software zu erreichen. Es basiert auf Interviews mit den beteiligten Ingenieuren, die die Komponententests entwickelt haben.
Einige der Lektionen sind:
quelle
Vielleicht ist die Frage, ob dies machbar und sinnvoll ist, nicht die hilfreichste Frage. Die wahrscheinlich praktischste Antwort ist die akzeptierte. Ich werde dies auf einer philosophischen Ebene analysieren.
Eine Abdeckung von 100% wäre ideal, aber im Idealfall wäre sie nicht erforderlich oder viel einfacher zu erreichen. Ich überlege lieber, ob es natürlich und menschlich ist, als dass es machbar oder vernünftig ist.
Das richtige Programmieren ist mit den heutigen Werkzeugen so gut wie unmöglich. Es ist sehr schwierig, Code zu schreiben, der völlig korrekt ist und keine Fehler aufweist. Es ist einfach nicht natürlich. Da es keine andere naheliegende Option gibt, wenden wir uns Techniken wie TDD und der Erfassung von Code zu. Aber solange das Endergebnis noch ein unnatürlicher Prozess ist, wird es Ihnen schwer fallen, die Leute dazu zu bringen, ihn konsequent und glücklich zu tun.
Das Erreichen einer 100% igen Code-Abdeckung ist eine unnatürliche Handlung. Für die meisten Menschen wäre es eine Form der Folter, sie dazu zu zwingen, dies zu erreichen.
Wir brauchen Prozesse, Werkzeuge, Sprachen und Code, die unseren natürlichen mentalen Modellen entsprechen. Wenn wir dies nicht tun, gibt es keine Möglichkeit, die Qualität eines Produkts zu testen.
Schauen Sie sich einfach die Software an, die es heute gibt. Das meiste ist ziemlich regelmäßig durcheinander. Wir wollen das nicht glauben. Wir möchten glauben, dass unsere Technologie magisch ist und uns glücklich machen. Deshalb ignorieren, entschuldigen und vergessen wir die meiste Zeit, in der unsere Technologie durcheinander kommt. Aber wenn wir die Dinge ehrlich beurteilen, ist die meiste Software heutzutage ziemlich beschissen.
Hier einige Versuche, die Codierung natürlicher zu gestalten:
https://github.com/jcoplien/trygve
https://github.com/still-dreaming-1/PurposefulPhp
Letzteres ist äußerst unvollständig und experimentell. Eigentlich ist es ein Projekt, das ich gestartet habe, aber ich glaube, es wäre ein großer Fortschritt für das Handwerk der Programmierung, wenn ich jemals die Zeit dafür aufbringen könnte, es fertigzustellen. Grundsätzlich ist es die Idee, dass, wenn Verträge die einzigen Aspekte eines Klassenverhaltens ausdrücken, die uns interessieren, und wir Verträge bereits als Code ausdrücken, warum nicht nur die Klassen- und Methodendefinitionen zusammen mit den Verträgen vorliegen. Auf diese Weise wären die Verträge der Code, und wir müssten nicht alle Methoden implementieren. Lassen Sie die Bibliothek herausfinden, wie Sie die Verträge für uns einhalten können.
quelle
Das Erreichen von 100% bei neuem Code sollte sehr erreichbar sein, und wenn Sie TDD üben, werden Sie dies wahrscheinlich standardmäßig tun, da Sie sehr absichtlich Tests für jede Zeile des Produktionscodes schreiben.
Bei vorhandenem Legacy-Code, der ohne Komponententests geschrieben wurde, kann es schwierig sein, da Legacy-Code häufig nicht für Komponententests geschrieben wurde und eine Menge Umgestaltung erfordern kann. Dieses Refactoring-Niveau ist in Anbetracht des Risikos und des Zeitplans oft nicht praktikabel, sodass Sie Kompromisse eingehen.
In meinem Team gebe ich eine Codeabdeckung von 100% an. Wenn im Code-Review weniger angezeigt wird, bespricht der technische Eigentümer der Komponente, warum mit dem Entwickler keine 100% erreicht wurden, und muss der Begründung des Entwicklers zustimmen. Wenn ein Problem zu 100% auftritt, wird der Entwickler häufig vor der Codeüberprüfung mit dem technischen Eigentümer sprechen. Wir haben festgestellt, dass es nicht so schwierig ist, regelmäßig 100% zu erreichen, wenn Sie sich erst einmal an die Gewohnheit gewöhnt haben und Techniken erlernen, mit denen Sie einige häufig auftretende Probleme umgehen können, indem Sie dem Legacy-Code Tests hinzufügen.
Michael Feathers Buch " Effektiv mit Legacy-Code arbeiten " war für uns von unschätzbarem Wert, da es Strategien für das Hinzufügen von Tests zu unserem Legacy-Code lieferte.
quelle
Nein, das ist nicht möglich und wird es auch nie sein. Wenn es möglich wäre, würde die gesamte Mathematik in den Finitismus fallen. Wie würden Sie beispielsweise eine Funktion testen, bei der zwei 64-Bit-Ganzzahlen verwendet und multipliziert wurden? Dies war schon immer mein Problem mit dem Testen und dem Überprüfen eines korrekten Programms. Für alles andere als die trivialsten Programme ist Testen im Grunde genommen nutzlos, da es nur eine kleine Anzahl von Fällen abdeckt. Es ist, als ob Sie 1.000 Zahlen überprüfen und sagen, Sie hätten die Goldbach-Vermutung bewiesen.
quelle