In einigen Organisationen ist es anscheinend Teil des Software-Release-Prozesses, Komponententests zu verwenden, aber zu jedem Zeitpunkt müssen alle Komponententests bestanden werden. Es könnte zum Beispiel einen Bildschirm geben, auf dem alle bestandenen Komponententests in Grün angezeigt werden - was gut sein soll.
Persönlich denke ich, dass dies aus den folgenden Gründen nicht so sein sollte:
Es fördert die Idee, dass Code perfekt sein sollte und keine Bugs existieren sollten - was in der realen Welt für ein Programm jeglicher Größe sicherlich unmöglich ist.
Es ist nicht ratsam, Komponententests auszudenken, die fehlschlagen werden. Oder sicherlich mit Unit-Tests kommen, die schwierig zu beheben wäre.
Wenn zu irgendeinem Zeitpunkt alle Komponententests bestanden werden, gibt es zu keinem Zeitpunkt ein umfassendes Bild über den Status der Software. Es gibt keine Roadmap / Ziel.
Es hält Schreibgerätetests von vornherein ab - vor der Implementierung.
Ich würde sogar vorschlagen, dass es nicht nötig ist, Software mit fehlgeschlagenen Unit-Tests zu veröffentlichen. Zumindest wissen Sie dann, dass einige Aspekte der Software Einschränkungen aufweisen.
Vermisse ich hier etwas? Warum erwarten Unternehmen, dass alle Komponententests bestanden werden? Lebt das nicht in einer Traumwelt? Und schreckt es nicht tatsächlich ein wirkliches Verständnis von Code ab?
quelle
Antworten:
Diese Frage enthält meiner Meinung nach mehrere Missverständnisse, aber das wichtigste, auf das ich mich konzentrieren möchte, ist, dass nicht zwischen lokalen Entwicklungszweigen, Trunk-, Staging- oder Release-Zweigen unterschieden wird.
In einer lokalen Entwicklungsabteilung ist es wahrscheinlich, dass zu fast jeder Zeit einige Unit-Tests fehlschlagen. Im Kofferraum ist es nur bis zu einem gewissen Grad akzeptabel, aber bereits ein starker Indikator, um die Dinge so schnell wie möglich zu beheben. Beachten Sie, dass fehlgeschlagene Unit-Tests im Kofferraum den Rest des Teams stören können, da jeder überprüfen muss, ob die letzte Änderung den Fehler verursacht hat.
In einem Staging- oder Release-Zweig sind fehlgeschlagene Tests "Roter Alarm". Dies zeigt, dass bei einem Änderungssatz ein Fehler aufgetreten ist, als er vom Trunk in den Release-Zweig zusammengeführt wurde.
Das Freigeben von Software mit einigen bekannten Fehlern unter einem bestimmten Schweregrad ist nicht unbedingt schlecht. Diese bekannten Störungen sollten jedoch keinen fehlerhaften Komponententest verursachen. Andernfalls muss man sich nach jedem Unit-Testlauf die 20 fehlgeschlagenen Unit-Tests ansehen und nacheinander prüfen, ob der Fehler akzeptabel war oder nicht. Dies wird umständlich, fehleranfällig und wirft einen großen Teil des Automatisierungsaspekts von Komponententests weg.
Wenn Sie wirklich Tests auf akzeptable, bekannte Fehler haben, verwenden Sie die Deaktivierungs- / Ignorierungsfunktion Ihres Unit-Test-Tools (sodass diese nicht standardmäßig, sondern nur bei Bedarf ausgeführt werden). Fügen Sie Ihrem Issue-Tracker außerdem ein Ticket mit niedriger Priorität hinzu, damit das Problem nicht vergessen wird.
quelle
Es ist gut Nein "soll es sein".
Nein. Es zeigt, dass Sie den Code so gut wie möglich getestet haben. Es ist durchaus möglich, dass Ihre Tests nicht jeden Fall abdecken. In diesem Fall werden Fehler möglicherweise in Fehlerberichten angezeigt, und Sie schreiben Tests, um die Probleme zu reproduzieren, und korrigieren die Anwendung, damit die Tests bestanden werden.
Fehlgeschlagene oder negative Tests schränken die Akzeptanz Ihrer Bewerbung fest ein. Die meisten mir bekannten Programme werden gegen ein "Datum" vom 30. Februar protestieren. Auch Entwickler, kreative Typen, die wir sind, wollen "ihre Babys" nicht zerbrechen. Die daraus resultierende Fokussierung auf "Happy-Path" -Fälle führt zu fragilen Anwendungen, die häufig nicht funktionieren.
So vergleichen Sie die Einstellung des Entwicklers und des Testers:
Dies sind radikal unterschiedliche Perspektiven, die für viele Entwickler schwer in Einklang zu bringen sind.
Sie schreiben keine Tests, um Arbeit für sich selbst zu machen. Sie schreiben Tests, um sicherzustellen, dass Ihr Code das tut, was er tun soll, und vor allem, dass er weiterhin das tut, was er tun soll, nachdem Sie seine interne Implementierung geändert haben.
Der einzige "Bild" -Test gibt Ihnen einen Schnappschuss, dass der Code zum Zeitpunkt des Tests "funktioniert". Wie es sich danach entwickelt, ist eine andere Geschichte.
Genau das sollten Sie tun. Schreiben Sie einen Test, der fehlschlägt (weil die Methode, die getestet wird, noch nicht implementiert wurde), und schreiben Sie dann den Methodencode, damit die Methode funktioniert und damit der Test bestanden wird. Das ist so ziemlich der Kern der testgetriebenen Entwicklung.
Wenn Sie Code mit fehlerhaften Tests freigeben, funktioniert ein Teil der Funktionalität nicht mehr wie zuvor. Dies kann eine absichtliche Handlung sein, da Sie einen Fehler behoben oder eine Funktion verbessert haben (aber Sie sollten den Test zuerst so geändert haben, dass er fehlgeschlagen ist, und dann die Fehlerbehebung / Verbesserung codiert haben, sodass der Test in diesem Prozess funktioniert). Wichtiger noch: Wir sind alle Menschen und machen Fehler. Wenn Sie den Code brechen, sollten Sie die Tests brechen, und diese gebrochenen Tests sollten Alarmglocken läuten lassen.
Wenn überhaupt, ist es in der lebenden Real World , anzuerkennen , dass Entwickler weder allwissend noch infallable sind, dass wir tun , Fehler machen und dass wir ein brauchen Sicherheitsnetz , uns zu fangen , ob und wann wir tun mess up!
Tests eingeben.
Vielleicht. Sie müssen nicht unbedingt die Implementierung von etwas verstehen, um Tests dafür zu schreiben (das ist ein Teil des Punktes von ihnen). Tests definieren das Verhalten und die Grenzen der Anwendung und stellen sicher, dass diese unverändert bleiben, sofern Sie sie nicht absichtlich ändern.
quelle
Sie sind es nicht - die testgetriebene Entwicklung basiert auf dem Gedanken, Tests nicht zu bestehen. Fehlgeschlagene Komponententests, um die Entwicklung voranzutreiben, fehlgeschlagene Akzeptanztests, um eine Geschichte voranzutreiben ...
Was Sie vermissen, ist Kontext ; Wo dürfen die Komponententests fehlschlagen?
Die übliche Antwort ist, dass Unit-Tests nur in privaten Sandboxen fehlschlagen dürfen.
Der Grundgedanke ist: In einer Umgebung, in der fehlerhafte Tests gemeinsam genutzt werden, ist es besonders schwierig zu verstehen, ob eine Änderung des Produktionscodes einen neuen Fehler verursacht hat. Der Unterschied zwischen Null und nicht Null ist viel einfacher zu erkennen und zu handhaben als der Unterschied zwischen N und nicht N.
Wenn Sie den gemeinsam genutzten Code sauber halten, können Entwickler die Arbeit fortsetzen. Wenn ich Ihren Code zusammenführen, brauche ich nicht Kontexte von dem Problem zu verschieben ich zu kalibrieren mein Verständnis davon , wie viele Tests zu lösen bezahlt werde werden sollte werden scheitern. Wenn der gemeinsame Code wird alle Tests vorbei, die alle Fehler angezeigt , wenn ich in meinen Änderungen zusammenführen muss Teil der Interaktion zwischen meinem Code und der bestehenden sauber Basislinie sein.
In ähnlicher Weise kann ein neuer Entwickler während des Einsteigens schneller produktiv werden, da er keine Zeit damit verbringen muss, herauszufinden, welche nicht bestandenen Tests "akzeptabel" sind.
Genauer gesagt: Die Disziplin besteht darin, dass Tests, die während des Builds ausgeführt werden, bestanden werden müssen.
Es ist, wie ich am besten beurteilen kann, nichts Falsches daran , fehlerhafte Tests zu haben, die deaktiviert sind .
In einer "Continuous Integration" -Umgebung geben Sie beispielsweise Code mit hoher Trittfrequenz weiter. Oft bedeutet die Integration nicht unbedingt, dass Ihre Änderungen release-fähig sein müssen. Es gibt eine Reihe von Dark Deploy-Techniken, die verhindern, dass der Datenverkehr in Abschnitte des Codes aufgeteilt wird, bis diese bereit sind.
Dieselben Techniken können auch zum Deaktivieren fehlgeschlagener Tests verwendet werden.
Eine der Übungen, die ich in einer Pressemitteilung durchlaufen habe, betraf die Entwicklung eines Produkts mit vielen nicht bestandenen Tests. Die Antwort bestand einfach darin, die Suite zu durchlaufen, die fehlgeschlagenen Tests zu deaktivieren und die einzelnen Tests zu dokumentieren . Dies ermöglichte es uns, schnell einen Punkt zu erreichen, an dem alle aktivierten Tests bestanden, und Management / Zielspender / Goldbesitzer konnten alle sehen, welche Trades wir gemacht hatten, um zu diesem Punkt zu gelangen, und fundierte Entscheidungen über Aufräumarbeiten im Vergleich zu neuen Arbeiten treffen.
Kurz gesagt: Es gibt andere Techniken zur Nachverfolgung von nicht erledigter Arbeit, als eine Reihe von fehlgeschlagenen Tests in der laufenden Suite zu belassen.
quelle
Es gibt viele gute Antworten, aber ich möchte einen weiteren Aspekt hinzufügen, von dem ich glaube, dass er noch nicht gut abgedeckt ist: Was genau ist der Sinn von Tests?
Unit-Tests sind nicht da, um zu überprüfen, ob Ihr Code fehlerfrei ist.
Ich denke, das ist das Hauptmissverständnis. Wenn dies ihre Rolle wäre, würde man in der Tat erwarten, dass Tests überall fehlschlagen. Aber stattdessen,
Unit-Tests stellen sicher, dass Ihr Code genau das tut, was Sie denken.
In extremen Fällen kann es die Überprüfung beinhaltet , dass bekannte Fehler sind nicht festgelegt. Der Punkt ist, die Kontrolle über Ihre Codebasis zu haben und versehentliche Änderungen zu vermeiden. Wenn Sie eine Änderung vornehmen, ist dies in Ordnung und es wird erwartet, dass einige Tests abgebrochen werden - Sie ändern das Verhalten des Codes. Der frisch gebrochene Test ist jetzt eine feine Spur dessen, was Sie geändert haben. Vergewissern Sie sich, dass alle Bruchstellen den Anforderungen Ihres Wechsels entsprechen. Wenn ja, aktualisieren Sie einfach die Tests und fahren Sie fort. Wenn nicht, ist Ihr neuer Code definitiv fehlerhaft. Gehen Sie zurück und korrigieren Sie ihn, bevor Sie ihn absenden!
Jetzt funktionieren alle oben genannten Funktionen nur, wenn alle Tests grün sind. Dies führt zu sehr positiven Ergebnissen: Genau so funktioniert der Code. Rote Tests haben diese Eigenschaft nicht. "Dies ist, was dieser Code nicht tut" ist selten eine nützliche Information.
Akzeptanztests können genau das sein, wonach Sie suchen.
Es gibt so etwas wie Abnahmetests. Sie können eine Reihe von Tests schreiben, die erfüllt sein müssen, um den nächsten Meilenstein aufzurufen. Diese sind in Ordnung, rot zu sein, denn dafür wurden sie entwickelt. Aber sie unterscheiden sich stark von Unit-Tests und können und sollten diese weder ersetzen.
quelle
Ich betrachte es als das Software-Äquivalent des Fenstersyndroms .
Arbeitstests zeigen mir, dass der Code von einer bestimmten Qualität ist und dass sich die Eigentümer des Codes darum kümmern.
Wann Sie sich für die Qualität interessieren sollten, hängt vielmehr davon ab, an welchem Quellcode-Zweig / Repository Sie arbeiten. Dev Code kann sehr wohl kaputte Tests haben, die darauf hinweisen, dass gerade gearbeitet wird (hoffentlich!).
Unterbrochene Tests an einer Zweigstelle / einem Repository für ein Live-System sollten sofort Alarmglocken läuten lassen. Wenn unterbrochene Tests weiterhin fehlschlagen oder dauerhaft als "ignorieren" markiert sind, sollten Sie damit rechnen, dass sich ihre Anzahl im Laufe der Zeit erhöht. Wenn diese nicht regelmäßig überprüft werden, wurde der Präzedenzfall festgelegt, dass gebrochene Tests in Ordnung sind.
Gebrochene Tests werden in vielen Läden so abwertend betrachtet, dass eine Einschränkung dahingehend besteht, ob gebrochener Code überhaupt festgeschrieben werden kann .
quelle
Hier ist der zugrunde liegende logische Irrtum:
Mit Unit - Tests, es IST gut , wenn alle Tests bestanden. Es ist AUCH GUT, wenn ein Test fehlschlägt. Die beiden brauchen sich nicht zu widersprechen.
Ein fehlgeschlagener Test ist ein Problem, das von Ihrem Werkzeug erfasst wurde, bevor es einen Benutzer erreichte. Es ist eine Gelegenheit, einen Fehler zu beheben, bevor er veröffentlicht wird. Und das ist auch gut so.
quelle
Die Antwort von Phill W ist großartig. Ich kann es nicht ersetzen.
Ich möchte mich jedoch auf einen anderen Teil konzentrieren, der möglicherweise Teil der Verwirrung war.
"zu jedem Zeitpunkt" überbewertet Ihren Fall. Wichtig ist, dass Komponententests nach der Implementierung einer bestimmten Änderung bestehen, bevor Sie mit der Implementierung einer weiteren Änderung beginnen.
So behalten Sie den Überblick, durch welche Änderung ein Fehler aufgetreten ist. Wenn die Komponententests nach der Implementierung von Änderung 25, aber vor der Implementierung von Änderung 26 fehlgeschlagen sind , wissen Sie, dass Änderung 25 den Fehler verursacht hat.
Während der Durchführung einer Änderung können die Komponententests natürlich fehlschlagen. Das hängt sehr davon ab, wie groß die Veränderung ist. Wenn ich ein Kernfeature neu entwickle, bei dem es sich nicht nur um eine geringfügige Änderung handelt, werde ich die Tests wahrscheinlich für eine Weile unterbrechen, bis ich die Implementierung meiner neuen Version der Logik abgeschlossen habe.
Dies kann zu Konflikten mit Teamregeln führen. Ich bin vor ein paar Wochen tatsächlich auf folgendes gestoßen:
Jede Regel wäre in Ordnung. Aber beide Regeln können nicht zusammenarbeiten. Wenn mir eine größere Änderung zugewiesen wird, die mehrere Tage in Anspruch nimmt, kann ich nicht beide Regeln gleichzeitig einhalten. Es sei denn, ich würde meine Änderungen jeden Tag kommentieren und sie erst unkommentiert übernehmen, nachdem alles erledigt war. Das ist nur unsinnige Arbeit.
In diesem Szenario ist das Problem hier nicht, dass Komponententests keinen Zweck haben. Es ist, dass das Unternehmen unrealistische Erwartungen hat . Ihr beliebiger Regelsatz deckt nicht alle Fälle ab, und die Nichteinhaltung der Regeln wird blind als Entwicklerfehler und nicht als Regelfehler angesehen (was in meinem Fall der Fall ist).
quelle
Wenn Sie nicht alle Komponententests reparieren, können Sie schnell in einen Zustand gelangen, in dem niemand beschädigte Tests repariert.
Ist falsch, da bestandene Unit-Tests nicht zeigen, dass der Code perfekt ist
Es ist nicht ratsam, Code zu entwickeln, der auch schwer zu testen ist, was aus gestalterischer Sicht gut ist
Code-Coverage kann da Abhilfe schaffen (obwohl es kein Allheilmittel ist). Auch Unit-Tests sind nur ein Aspekt des Testens - Sie möchten auch Integrations- / Abnahmetests.
quelle
Um ein paar Punkte zu den bereits guten Antworten hinzuzufügen ...
Dies zeigt einen Mangel an Verständnis für einen Freigabeprozess. Ein Testfehler kann auf eine geplante Funktion unter TDD hinweisen, die noch nicht implementiert ist. oder es weist auf ein bekanntes Problem hin, dessen Behebung für eine zukünftige Version geplant ist; oder es kann einfach etwas sein, bei dem das Management entschieden hat, dass dies nicht wichtig genug ist, um es zu beheben, da es unwahrscheinlich ist, dass Kunden es bemerken. Entscheidend ist, dass das Management über den Misserfolg urteilt.
Andere Antworten haben die Grenzen des Testens abgedeckt.
Ich verstehe nicht, warum Sie die Beseitigung von Fehlern für einen Nachteil halten. Wenn Sie keinen Code bereitstellen möchten, den Sie nach bestem Wissen und Gewissen überprüft haben und der das soll, warum arbeiten Sie dann überhaupt mit Software?
Warum muss es eine Roadmap geben?
Unit-Tests prüfen zunächst, ob die Funktionalität funktioniert, stellen dann aber (als Regressionstests) sicher, dass Sie nicht versehentlich etwas kaputt gemacht haben. Für alle Funktionen mit vorhandenen Komponententests gibt es keine Roadmap . Es ist bekannt, dass jede Funktion funktioniert (innerhalb der Testgrenzen). Wenn dieser Code fertig ist, gibt es keine Roadmap, da keine weiteren Arbeiten erforderlich sind.
Als professionelle Ingenieure müssen wir die Falle der Vergoldung vermeiden. Bastler können es sich leisten, Zeit damit zu verschwenden, an den Rändern mit etwas zu basteln, das funktioniert. Als Profis müssen wir ein Produkt liefern. Das bedeutet, dass wir etwas zum Laufen bringen, überprüfen, ob es funktioniert, und mit dem nächsten Job fortfahren.
quelle
Nicht wahr. warum denkst du, ist es unmöglich? Hier ein Beispiel für ein Programm, das funktioniert:
In diesem Fall handelt es sich möglicherweise nicht um einen Komponententest, sondern um einen Integrationstest, wenn dies kompliziert ist
Richtig, es wird aus einem bestimmten Grund Unit- Test genannt. Es überprüft eine kleine Code-Einheit.
Entwickler
werdenSchreiben Sie keine Tests, wenn Sie deren Vorteile nicht verstehenvon Natur aus (es sei denn, sie kamen aus der Qualitätssicherung)quelle
Ganz bestimmt nicht. Es fördert die Idee, dass Ihre Tests nicht scheitern sollten, nicht mehr und nicht weniger. Angenommen, Tests (auch viele) sagen etwas über "perfekt" oder "keine Fehler" aus, ist ein Irrtum. Die Entscheidung, wie flach oder tief Ihre Tests sein sollten, ist ein wesentlicher Bestandteil des Schreibens guter Tests und der Grund, warum wir eindeutig getrennte Testkategorien haben ("Unit" -Tests, Integrationstests, "Szenarien" im Gurken-Sinne usw.).
Bei der testgetriebenen Entwicklung ist es obligatorisch, dass jeder Komponententest zuerst fehlschlägt, bevor mit dem Code begonnen wird. Es wird aus genau diesem Grund "Rot-Grün-Zyklus" (oder "Rot-Grün-Refaktor-Zyklus") genannt.
Tests sind eher ein Mikrotor. Bei der testgetriebenen Entwicklung schreibt der Programmierer zuerst einen Test (Singular) und hat dann das klare Ziel, Code zu implementieren. dann der nächste Test und so weiter.
Die Funktion der Tests besteht darin, nicht vollständig zu sein, bevor Code geschrieben wird.
Wenn dies richtig gemacht wird, in einer Sprache und mit einer Testbibliothek, die für diesen Ansatz gut geeignet ist, kann dies die Entwicklung tatsächlich massiv beschleunigen, da die Fehlermeldungen (Ausnahmen / Stacktraces) den Entwickler direkt darauf hinweisen können, wo er die Arbeit ausführen muss Nächster.
Ich verstehe nicht, wie diese Aussage zutreffen würde. Schreibtests sollten idealerweise Teil der Implementierung sein.
Weil Unternehmen erwarten, dass Tests für den Code relevant sind. Wenn Sie Tests schreiben, die erfolgreich sind, haben Sie einen Teil Ihrer Anwendung dokumentiert und nachgewiesen, dass die Anwendung das tut, was es sagt (der Test). Nicht mehr und nicht weniger.
Ein sehr großer Teil des Testens ist die "Regression". Sie möchten in der Lage sein, neuen Code sicher zu entwickeln oder umzugestalten. Mit einer großen Anzahl von Grüntests können Sie dies tun.
Dies geht von einer organisatorischen zu einer psychologischen Ebene. Ein Entwickler, der weiß, dass seine Fehler höchstwahrscheinlich von den Tests erfasst werden, hat viel mehr Freiheit, intelligente und mutige Lösungen für die Probleme zu finden, die er lösen muss. Andererseits wird ein Entwickler, der keine Tests hat, nach einiger Zeit zum Stillstand kommen (aus Angst), weil er nie weiß, ob eine Änderung den Rest der Anwendung beeinträchtigt.
Nein. Die Arbeit mit einer testgetriebenen Anwendung ist reine Freude - es sei denn, Sie mögen das Konzept aus irgendeinem Grund ("Mehraufwand" usw. usw.) nicht, den wir in einer anderen Frage diskutieren können.
Absolut nicht, warum sollte es?
Sie finden viele große Open-Source-Projekte (für die das Management des "Verstehens" und des Know-hows über den Code ein sehr dringendes Thema ist), die die Tests tatsächlich als Hauptdokumentation der Software verwenden, indem sie nicht nur Tests sind, sondern Stellen Sie auch echte, funktionierende, syntaktisch korrekte Beispiele für Benutzer oder Entwickler der Anwendung / Bibliothek bereit. Dies funktioniert oft hervorragend.
Offensichtlich ist es schlecht, schlechte Tests zu schreiben. Das hat aber nichts mit der Funktion von Tests an sich zu tun.
quelle
(Aus meinen ursprünglichen Kommentaren)
Es gibt einen Unterschied zwischen erforderlicher Funktionalität und zukünftigen Zielen. Tests sind auf die erforderliche Funktionalität ausgerichtet: Sie sind präzise, formal und ausführbar. Wenn sie fehlschlagen, funktioniert die Software nicht. Zukünftige Ziele sind möglicherweise nicht präzise oder formal, geschweige denn ausführbar. Sie sollten daher in natürlicher Sprache verfasst werden, z. B. in Issue- / Bug-Trackern, Dokumentationen, Kommentaren usw.
Versuchen Sie als Übung, den Ausdruck "Komponententest" in Ihrer Frage durch "Compilerfehler" (oder "Syntaxfehler", wenn kein Compiler vorhanden ist) zu ersetzen. Es ist offensichtlich, dass ein Release keine Compilerfehler enthalten sollte, da es unbrauchbar wäre. Dennoch sind Compiler- und Syntaxfehler der normale Zustand auf dem Computer eines Entwicklers, wenn dieser Code schreibt. Die Fehler verschwinden erst, wenn sie beendet sind. und genau dann sollte der Code gepusht werden. Ersetzen Sie nun "Compilerfehler" in diesem Absatz durch "Komponententest" :)
quelle
Der Zweck automatisierter Tests ist es, Ihnen so früh wie möglich mitzuteilen, wenn Sie etwas kaputt gemacht haben . Der Workflow sieht ungefähr so aus:
Wenn Ihre Tests bereits fehlgeschlagen sind, funktioniert Schritt 3 nicht so effektiv - die Tests schlagen fehl, aber Sie wissen nicht, ob dies bedeutet, dass Sie etwas kaputt gemacht haben oder nicht, ohne dies zu untersuchen. Vielleicht könnten Sie die Anzahl der fehlgeschlagenen Tests zählen, aber dann könnte eine Änderung einen Fehler beheben und einen anderen brechen, oder ein Test könnte aus einem anderen Grund fehlschlagen. Dies bedeutet, dass Sie einige Zeit warten müssen, bis Sie wissen, ob ein Fehler aufgetreten ist, entweder bis alle Probleme behoben wurden oder bis alle fehlgeschlagenen Tests untersucht wurden.
Die Fähigkeit von Komponententests, neu eingeführte Fehler so früh wie möglich zu finden, ist das Wertvollste an automatisierten Tests - je länger ein Fehler unentdeckt bleibt, desto teurer ist die Behebung.
Tests für Dinge, die nicht funktionieren, sagen Ihnen nichts - schreiben Sie Komponententests für Dinge, die funktionieren oder die Sie gerade reparieren. Dies bedeutet nicht, dass Ihre Software fehlerfrei ist. Es bedeutet, dass keiner der Fehler, für die Sie zuvor Komponententests geschrieben haben, erneut aufgetreten ist.
Wenn es für Sie funktioniert, schreiben Sie Tests im Voraus, checken Sie sie einfach nicht in Ihren Master / Kofferraum ein, bis sie bestanden sind.
Unit-Tests sind nicht für die Festlegung einer Roadmap / eines Ziels gedacht. Verwenden Sie stattdessen einen Rückstand? Wenn alle Ihre Tests bestanden sind, ist das "große Ganze", dass Ihre Software nicht kaputt ist (wenn Ihre Testabdeckung gut ist). Gut gemacht!
quelle
Die vorhandenen Antworten sind sicherlich gut, aber ich habe niemanden gesehen, der dieses grundlegende Missverständnis in der Frage angesprochen hat:
Sicherlich wird das nicht wahr sein. Während ich Software entwickle, ist NCrunch meistens entweder braun (Buildfehler) oder rot (Testfehler).
Wenn NCrunch grün sein muss (alle Tests bestehen), kann ich ein Commit an den Quellcodeverwaltungsserver senden, da zu diesem Zeitpunkt andere möglicherweise von meinem Code abhängig sind.
Dies speist sich auch in das Thema der Erstellung neuer Tests ein: Tests sollten die Logik und das Verhalten des Codes bestätigen. Randbedingungen, Fehlerbedingungen usw. Wenn ich neue Tests schreibe, versuche ich, diese "Hot Spots" im Code zu identifizieren.
Unit-Tests dokumentieren, wie mein Code aufgerufen werden soll - Voraussetzungen, erwartete Ausgaben usw.
Wenn ein Test nach einer Änderung abbricht, muss ich entscheiden, ob der Code oder der Test fehlerhaft ist.
Nebenbei bemerkt, Unit-Tests gehen manchmal mit Test Driven Development einher. Eines der Prinzipien von TDD ist, dass gebrochene Tests Ihre Wegweiser sind. Wenn ein Test fehlschlägt, müssen Sie den Code korrigieren, damit der Test bestanden wird. Hier ist ein konkretes Beispiel aus dieser Woche:
Hintergrund : Ich habe eine Bibliothek geschrieben, die von unseren Entwicklern zur Validierung von Oracle-Abfragen verwendet wird. Wir hatten Tests, bei denen festgestellt wurde, dass die Abfrage mit einem erwarteten Wert übereinstimmte, was Groß- und Kleinschreibung bedeutete (dies ist nicht in Oracle der Fall) und ungültige Abfragen fröhlich genehmigte, solange sie vollständig mit dem erwarteten Wert übereinstimmten.
Stattdessen analysiert meine Bibliothek die Abfrage mithilfe von Antlr und einer Oracle 12c-Syntax und schließt dann verschiedene Zusicherungen in den Syntaxbaum selbst ein. Dinge wie, es ist gültig (es wurden keine Analysefehler ausgelöst), alle seine Parameter werden von der Parameterauflistung erfüllt, alle vom Datenleser gelesenen erwarteten Spalten sind in der Abfrage vorhanden usw. All dies sind Elemente, die durchgeglitten sind Produktion zu verschiedenen Zeiten.
Einer meiner Kollegen schickte mir am Montag eine Anfrage, die am Wochenende fehlgeschlagen war (oder besser gesagt, erfolgreich war, als es hätte fehlschlagen sollen). Meine Bibliothek sagte, dass die Syntax in Ordnung sei, aber sie explodierte, als der Server versuchte, sie auszuführen. Und als er sich die Abfrage ansah, war es offensichtlich, warum:
Ich habe das Projekt geladen und einen Komponententest hinzugefügt, der bestätigt, dass diese Abfrage ungültig sein sollte. Offensichtlich ist der Test fehlgeschlagen.
Als nächstes gedebuggt ich den fehlerhaften Test, durch den Code trat , wo ich es erwartet , dass die Ausnahme zu werfen, und herausgefunden, dass Antlr wurde auf dem offenen paren Fehler verursacht, nicht nur der vorherige Code in eine Art und Weise erwartet. Ich habe den Code geändert und festgestellt, dass der Test jetzt grün (bestanden) ist und dass keiner der anderen in den Prozess eingebrochen, festgeschrieben und weitergeleitet wurde.
Das hat vielleicht 20 Minuten gedauert, und dabei habe ich die Bibliothek tatsächlich erheblich verbessert, da sie jetzt eine ganze Reihe von Fehlern unterstützt, die sie zuvor ignoriert hatte. Wenn ich keine Komponententests für die Bibliothek gehabt hätte, hätte das Nachforschen und Beheben des Problems Stunden dauern können.
quelle
Ein Punkt, von dem ich glaube, dass er nicht aus früheren Antworten hervorgeht, ist, dass es einen Unterschied zwischen internen und externen Tests gibt (und ich denke, dass viele Projekte nicht sorgfältig genug sind, um die beiden zu unterscheiden). Ein interner Test prüft, ob eine interne Komponente ordnungsgemäß funktioniert. Ein externer Test zeigt, dass das System insgesamt so funktioniert, wie es sollte. Es ist natürlich durchaus möglich, dass Komponenten ausfallen, die nicht zum Ausfall des Systems führen (möglicherweise gibt es eine Funktion der Komponente, die das System nicht verwendet, oder das System erholt sich möglicherweise nach einem Ausfall des Komponente). Ein Komponentenfehler, der nicht zu einem Systemfehler führt, sollte Sie nicht davon abhalten, die Version zu veröffentlichen.
Ich habe Projekte gesehen, die durch zu viele interne Komponententests gelähmt sind. Jedes Mal, wenn Sie versuchen, eine Leistungsverbesserung zu implementieren, brechen Sie Dutzende von Tests ab, da Sie das Verhalten von Komponenten ändern, ohne das äußerlich sichtbare Verhalten des Systems zu ändern. Dies führt zu einem Mangel an Agilität im gesamten Projekt. Ich glaube, dass die Investition in externe Systemtests sich im Allgemeinen viel besser auszahlt als die Investition in interne Komponententests, insbesondere wenn es sich um sehr einfache Komponenten handelt.
Wenn Sie vorschlagen, dass nicht bestandene Komponententests keine Rolle spielen, frage ich mich, ob Sie das im Sinn haben? Vielleicht sollten Sie den Wert der Komponententests einschätzen und diejenigen ausschließen, die mehr Probleme verursachen als sie wert sind, und sich mehr auf Tests konzentrieren, die das äußerlich sichtbare Verhalten der Anwendung verifizieren.
quelle
"Aber zu jedem Zeitpunkt müssen alle Komponententests bestanden sein"
Wenn das die Einstellung in Ihrem Unternehmen ist, ist das ein Problem. Zu einem BESTIMMTEN Zeitpunkt, dh wenn wir erklären, dass der Code bereit ist, in die nächste Umgebung zu wechseln, sollten alle Komponententests erfolgreich sein. Während der Entwicklung sollten wir jedoch routinemäßig damit rechnen, dass viele Komponententests fehlschlagen.
Keine vernünftige Person erwartet von einem Programmierer, dass er seine Arbeit beim ersten Versuch perfekt macht. Was wir vernünftigerweise erwarten, ist, dass er so lange daran arbeitet, bis keine Probleme mehr bekannt sind.
"Es ist nicht ratsam, Komponententests auszudenken, die scheitern werden. Oder Sie müssen sich Komponententests einfallen lassen, deren Behebung schwierig wäre." Wenn jemand in Ihrer Organisation der Meinung ist, dass er einen möglichen Test nicht erwähnen sollte, weil dieser fehlschlagen könnte, und mehr Arbeit zur Behebung veranlasst, ist diese Person für ihren Job völlig unqualifiziert. Das ist eine katastrophale Einstellung. Möchten Sie einen Arzt, der sagt: "Wenn ich eine Operation mache, überprüfe ich absichtlich nicht, ob die Stiche richtig sind, denn wenn ich sie nicht sehe, muss ich zurückgehen und sie wiederholen und das wird die Beendigung der Operation verlangsamen "?
Wenn das Team Programmierern feindlich gesinnt ist, die Fehler identifizieren, bevor der Code in die Produktion geht, haben Sie ein echtes Problem mit der Einstellung dieses Teams. Wenn das Management Programmierer bestraft, die Fehler identifizieren, die die Lieferung verlangsamen, besteht die Wahrscheinlichkeit, dass Ihr Unternehmen in Konkurs geht.
Ja, es ist sicher richtig, dass manchmal rationale Leute sagen: "Wir nähern uns der Frist, dies ist ein triviales Problem und es lohnt sich nicht, die Ressourcen zu verwenden, die es momentan braucht, um es zu beheben." Aber Sie können diese Entscheidung nicht rational treffen, wenn Sie es nicht wissen. Es ist vernünftig, eine Fehlerliste genau zu untersuchen und Prioritäten und Zeitpläne zuzuweisen, um sie zu beheben. Es ist töricht, sich bewusst über Probleme hinwegzusetzen, damit Sie diese Entscheidung nicht treffen müssen. Glaubst du, der Kunde wird es nicht herausfinden, nur weil du es nicht wissen wolltest?
quelle
Dies ist ein konkretes Beispiel für eine Bestätigungsverzerrung , bei der Menschen dazu neigen, Informationen zu suchen, die ihre bestehenden Überzeugungen bestätigen.
Ein berühmtes Beispiel dafür ist das 2,4,6-Spiel.
Die meisten Leute entscheiden sich für eine Regel: "Die Lücke zwischen der 1. und 2. Ziffer ist die gleiche wie die Lücke zwischen der 2. und 3. Ziffer."
Sie werden einige Zahlen testen:
Sie sagen: "Ja, jede Beobachtung bestätigt meine Hypothese, es muss wahr sein." Und verkünde ihre Regel der Person, die das Rätsel gibt.
Aber sie haben nie ein einziges "Scheitern" bei einem Satz von drei Zahlen erhalten. Die Regel könnte einfach lauten: "Die drei Zahlen müssen Zahlen sein" für alle Informationen, die sie tatsächlich haben.
Die Regel ist eigentlich nur, dass die Zahlen in aufsteigender Reihenfolge sind. Menschen bekommen dieses Rätsel in der Regel nur dann richtig, wenn sie auf Fehler testen. Die meisten Leute verstehen es falsch, indem sie eine spezifischere Regel wählen und nur Zahlen testen, die diese spezifische Regel erfüllen.
Was die Gründe angeht, warum Menschen auf Bestätigungsvoreingenommenheit verfallen und Unit-Tests als Anzeichen für ein Problem misslingen, gibt es viele Psychologen, die die Bestätigungsvoreingenommenheit besser erklären können als ich. Im Grunde kommt es darauf an, dass Menschen es nicht mögen, falsch zu liegen, und mit echten Versuchen zu kämpfen sich als falsch erweisen.
quelle