Warum scheitern Unit-Tests als schlecht?

93

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:

  1. 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.

  2. Es ist nicht ratsam, Komponententests auszudenken, die fehlschlagen werden. Oder sicherlich mit Unit-Tests kommen, die schwierig zu beheben wäre.

  3. 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.

  4. 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?

user619818
quelle
Kommentare sind nicht für eine längere Diskussion gedacht. Diese Unterhaltung wurde in den Chat verschoben .
maple_shaft

Antworten:

270

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.

Ich würde sogar vorschlagen, dass es nicht nötig ist, Software mit fehlgeschlagenen Unit-Tests zu veröffentlichen.

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.

Doc Brown
quelle
18
Ich denke, das ist die wahre Antwort. OP erwähnt "Freigabeprozess" und "einige Bildschirme [die Testergebnisse zeigen]", die sich wie ein Build-Server anhören. Release ist nicht dasselbe wie Entwicklung (nicht in der Produktion entwickeln!); Es ist in Ordnung, fehlerhafte Tests in dev zu haben, sie sind wie TODOs. Sie sollten alle grün (FERTIG) sein, wenn sie auf den Build-Server übertragen werden.
Warbo
7
Eine viel bessere Antwort als die mit der höchsten Bewertung. Es zeigt ein Verständnis, woher die Operation kommt, ohne sie über eine ideale Weltsituation zu unterrichten, erkennt die Möglichkeit bekannter Fehler (für die nicht die gesamte Roadmap zur Behebung eines seltenen Eckfalles ausgelassen wird) und erklärt, dass Komponententests nur auf jeden Fall durchgeführt werden sollten in einem Release-Zweig / -Prozess grün sein.
Sebastiaan van den Broek
5
@SebastiaanvandenBroek: danke für deine positive antwort. Nur um dies klar zu machen: IMHO-Tests mit fehlgeschlagenen Einheiten sollten selbst im Kofferraum selten sein, da solche Ausfälle zu oft das gesamte Team stören, nicht nur denjenigen, der die Änderung vorgenommen hat, die den Ausfall verursacht hat.
Doc Brown
4
Ich denke, das Problem hier ist, dass alle automatisierten Tests Komponententests sind. Viele Test-Frameworks bieten die Möglichkeit, Tests zu markieren, bei denen ein Fehlschlagen zu erwarten ist (häufig als XFAIL bezeichnet). (Dies unterscheidet sich von einem Test, der ein Fehlerergebnis erfordert. XFAIL-Tests wären im Idealfall erfolgreich, aber nicht.) Die Testsuite besteht diese weiterhin, wenn diese fehlschlagen. Der häufigste Anwendungsfall sind Dinge, die nur auf einigen Plattformen fehlschlagen (und auf diesen nur XFAIL), aber die Verwendung der Funktion zum Verfolgen von Dingen, für deren Behebung derzeit zu viel Arbeit erforderlich ist, liegt ebenfalls im Rahmen des Möglichen. Diese Art von Tests sind jedoch normalerweise keine Komponententests.
Kevin Cathcart
1
+1, obwohl ich einen kleinen Zusatz (in Fettdruck) zu diesem Satz vorschlage: "Dies wird umständlich, fehleranfällig, bedingt, dass Fehler in der Testsuite als Rauschen ignoriert werden und ein großer Teil des Automatisierungsaspekts von Komponententests verworfen wird .
mtraceur
228

... alle Unit-Tests in grün abschließen - das soll gut sein.

Es ist gut Nein "soll es sein".

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.

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.

Es ist nicht ratsam, Komponententests auszudenken, die fehlschlagen 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:

  • Ein Entwickler stoppt, sobald der Code das tut, was er möchte.
  • Ein Tester stoppt, wenn der Code nicht mehr unterbrochen werden kann.

Dies sind radikal unterschiedliche Perspektiven, die für viele Entwickler schwer in Einklang zu bringen sind.

Oder sicherlich mit Unit-Tests kommen, die schwierig zu beheben wäre.

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.

  • Debugging „beweist“ , dass der Code tut , was Sie es wollen heute .
  • Tests "beweisen", dass der Code im Laufe der Zeit immer noch das tut, was Sie wollen .

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.

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.

Es hält Schreibgerätetests von vornherein ab - vor der Implementierung.

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.

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.

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.

Lebt das nicht in einer Traumwelt?

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.

Und schreckt es nicht tatsächlich ein wirkliches Verständnis von Code ab?

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.

Phill W.
quelle
7
@Tibos: Das Deaktivieren eines Tests ist wie das Auskommentieren einer Funktion. Sie haben die Versionskontrolle. Benutze es.
Kevin
6
@ Kevin Ich weiß nicht, was du mit "benutze es" meinst. Ich markiere einen Test als "übersprungen" oder "ausstehend" oder wie auch immer mein Testläufer es vorsieht, und übergebe dieses Übersprung-Tag der Versionskontrolle.
dcorking
4
@dcorking: Ich meine, kommentiere den Code nicht aus, lösche ihn. Wenn Sie später entscheiden, dass Sie es benötigen, stellen Sie es über die Versionskontrolle wieder her. Das Festschreiben eines deaktivierten Tests ist nicht anders.
Kevin
4
"Es ist durchaus möglich, dass Ihre Tests nicht jeden Fall abdecken." Ich würde so weit gehen zu sagen, dass Sie definitiv nicht jeden Fall für jedes nicht-triviale Stück Code abgedeckt haben.
corsiKa
6
@Tibos Befürworter von Unit-Tests sagen, dass die Zykluszeit vom Schreiben eines fehlgeschlagenen Tests bis zum Schreiben des Codes für diesen klein sein sollte (z. B. 20 Minuten. Einige behaupten 30 Sekunden). Wenn Sie keine Zeit haben, den Code sofort zu schreiben, ist er wahrscheinlich viel zu komplex. Wenn es nicht komplex ist, löschen Sie den Test, da er neu geschrieben werden kann, wenn das abgelegte Feature erneut hinzugefügt wird. Warum nicht auskommentieren? Sie wissen nicht , dass die Funktion wird immer wieder hinzugefügt werden, so dass der auf Kommentar - Test (oder Code) ist nur Lärm.
CJ Dennis
32

Warum scheitern Unit-Tests als schlecht?

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.

VoiceOfUnreason
quelle
Ich hätte gesagt "Es gibt nichts auszusetzen, wenn Tests nicht bestanden haben, die deaktiviert sind ".
CJ Dennis
Diese Änderung verdeutlicht mit Sicherheit die Bedeutung. Danke.
VoiceOfUnreason
26

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.

Frax
quelle
2
Ich musste einmal eine Bibliothek durch eine andere ersetzen. Durch Unit-Tests konnte ich sicherstellen, dass alle Eckfälle nach dem neuen Code weiterhin gleich behandelt wurden.
Thorbjørn Ravn Andersen
24

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 .

Robbie Dee
quelle
9
Wenn Tests dokumentieren, wie ein System ist, sollten sie auf jeden Fall immer bestanden werden - wenn nicht, bedeutet dies, dass die Invarianten gebrochen sind. Wenn sie jedoch dokumentieren, wie ein System sein soll , können auch fehlgeschlagene Tests ihre Verwendung finden - sofern Ihr Unit-Testing-Framework eine gute Möglichkeit bietet, sie als "bekannte Probleme" zu kennzeichnen und wenn Sie sie mit einem Element verknüpfen in Ihrem Issue Tracker. Ich denke, beide Ansätze haben ihre Vorzüge.
Luaan
1
@Luaan Ja, das setzt eher voraus, dass alle Unit-Tests gleich erstellt werden. Es ist sicherlich nicht ungewöhnlich, dass Build-Manager die Tests anhand bestimmter Attribute in Segmente unterteilen, je nachdem, wie lange sie ausgeführt werden, wie spröde sie sind und nach verschiedenen anderen Kriterien.
Robbie Dee
Diese Antwort ist großartig aus meiner eigenen Erfahrung. Sobald sich einige Leute daran gewöhnt haben, eine Reihe von fehlgeschlagenen Tests zu ignorieren oder die Best Practices in einigen Punkten zu brechen, vergehen einige Monate, und Sie werden feststellen, dass% der ignorierten Tests dramatisch ansteigen und die Codequalität auf "Hack-Script" -Niveau sinkt . Und es wird sehr schwer sein, alle an den Prozess zu erinnern.
usr-local-ΕΨΗΕΛΩΕΨΗΕΛ
11

Hier ist der zugrunde liegende logische Irrtum:

Wenn es gut ist, wenn alle Tests bestanden wurden, muss es schlecht sein, wenn Tests fehlschlagen.

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.

Joel Coehoorn
quelle
Interessante Gedanken. Ich sehe den Irrtum der Frage eher so: "Da es gut ist, wenn ein Komponententest fehlschlägt, ist es schlecht, wenn alle Tests bestanden werden".
Doc Brown
Während Ihr letzter Absatz ein guter Punkt ist, scheint es, dass das Problem eher ein Missverständnis von "zu jedem Zeitpunkt, zu dem alle Komponententests bestanden werden müssen" (wie die akzeptierte Antwort anzeigt) und dem Punkt der Komponententests ist.
Dukeling
9

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.

In einigen Organisationen ist es anscheinend Teil des Software-Release-Prozesses, Komponententests zu verwenden, aber zu jedem Zeitpunkt müssen alle Komponententests bestanden werden

"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:

  • Jedes Commit / Push verursacht einen Build. Der Build darf niemals fehlschlagen (wenn dies der Fall ist oder ein Test fehlschlägt, wird der übergebende Entwickler dafür verantwortlich gemacht).
  • Von jedem Entwickler wird erwartet, dass er seine Änderungen (auch wenn sie unvollständig sind) am Ende des Tages vornimmt, damit die Teamleiter morgens Codeüberprüfungen durchführen können.

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).

Flater
quelle
3
Der einzige Weg , dies kann arbeiten , ist Verzweigung zu verwenden, so dass die Devs begehen und schieben Zweige verfügen, die nicht brauchen sauber zu bauen , während unvollständig, sondern verpflichtet sich , den Kern Zweig erstellen einen Build auslösen, die sauber aufbauen sollte.
Gwyn Evans
1
Es ist absurd, unvollständige Änderungen durchzusetzen. Ich sehe keine Rechtfertigung dafür. Warum nicht Codeüberprüfung, wenn die Änderung abgeschlossen ist?
Callum Bradbury
Zum einen können Sie so schnell sicherstellen, dass der Code nicht nur auf dem Laptop / der Workstation des Entwicklers gespeichert wird, wenn die Festplatte nicht mehr funktioniert oder auf andere Weise verloren geht Es gibt nur eine begrenzte Anzahl gefährdeter Arbeiten.
Gwyn Evans
1
Feature-Flags korrigieren das scheinbare Paradoxon.
RubberDuck
1
@Flater ja, auch zur Überarbeitung vorhandener Logik.
RubberDuck
6

Wenn Sie nicht alle Komponententests reparieren, können Sie schnell in einen Zustand gelangen, in dem niemand beschädigte Tests repariert.

  1. Ist falsch, da bestandene Unit-Tests nicht zeigen, dass der Code perfekt ist

  2. Es ist nicht ratsam, Code zu entwickeln, der auch schwer zu testen ist, was aus gestalterischer Sicht gut ist

  3. 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.

jk.
quelle
6

Um ein paar Punkte zu den bereits guten Antworten hinzuzufügen ...

Zu jedem Zeitpunkt müssen jedoch alle Komponententests bestanden werden

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.

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.

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?

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.

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.

Graham
quelle
6

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.

Nicht wahr. warum denkst du, ist es unmöglich? Hier ein Beispiel für ein Programm, das funktioniert:

public class MyProgram {
  public boolean alwaysTrue() {
    return true;
  }

  @Test
  public void testAlwaysTrue() {
    assert(alwaysTrue() == true);
  }
}

Es ist nicht ratsam, Komponententests auszudenken, die fehlschlagen werden. Oder sicherlich mit Unit-Tests kommen, die schwierig zu beheben wäre.

In diesem Fall handelt es sich möglicherweise nicht um einen Komponententest, sondern um einen Integrationstest, wenn dies kompliziert ist

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.

Richtig, es wird aus einem bestimmten Grund Unit- Test genannt. Es überprüft eine kleine Code-Einheit.

Es hält Schreibgerätetests von vornherein ab - vor der Implementierung.

Entwickler werdenSchreiben Sie keine Tests, wenn Sie deren Vorteile nicht verstehenvon Natur aus (es sei denn, sie kamen aus der Qualitätssicherung)

user7294900
quelle
„Entwickler werden von Natur aus davon abhalten, Tests zu schreiben“ - das ist völliger Unsinn. Ich arbeite bei einer ganzen Firma von Entwicklern, die TDD und BDD praktizieren.
RubberDuck
@RubberDuck Ich habe versucht, auf eine "Tatsache" zu antworten, und ich habe übertrieben. Ich werde Update
user7294900
"X wird davon abgehalten, Y zu tun, wenn sie die Vorteile von Y nicht verstehen" gilt für nahezu jedes X und Y, sodass diese Aussage wahrscheinlich nicht besonders nützlich ist. Es wäre wahrscheinlich sinnvoller, die Vorteile des Schreibens der Tests im Vorfeld zu erläutern.
Dukeling
2
"unmöglich für ein Programm jeder Größe" bedeutet nicht "alle Programme, egal welche Größe", sondern "jedes signifikante Programm (mit einer nicht trivialen Länge)". Ihr versuchtes Gegenbeispiel ist nicht anwendbar, weil es nicht " t ein wichtiges und nützliches Programm.
Ben Voigt
@BenVoigt Ich glaube nicht, dass ich ein "signifikantes Programm" als Antwort geben soll.
user7294900
4

Es fördert die Idee, dass Code perfekt sein und keine Bugs existieren sollten

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.).

Es ist nicht ratsam, Komponententests auszudenken, die fehlschlagen werden. Oder sicherlich mit Unit-Tests kommen, die schwierig zu beheben wäre.

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.

  • Ohne das Fehlschlagen des Tests wissen Sie nicht, ob der Code tatsächlich durch den Test getestet wird. Die beiden könnten überhaupt nicht verwandt sein.
  • Wenn Sie den Code so ändern , dass der Test genau von Rot auf Grün wechselt, nicht mehr und nicht weniger, können Sie sich ziemlich sicher sein, dass Ihr Code das tut, was er tun soll, und nicht viel mehr (was Sie möglicherweise nie brauchen).

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.

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.

Es hält Schreibgerätetests von vornherein ab - vor der Implementierung.

Ich verstehe nicht, wie diese Aussage zutreffen würde. Schreibtests sollten idealerweise Teil der Implementierung sein.

Vermisse ich hier etwas? Warum erwarten Unternehmen, dass alle Komponententests bestanden werden?

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.

Lebt das nicht in einer Traumwelt?

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.

Und schreckt es nicht tatsächlich ein wirkliches Verständnis von Code ab?

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.

AnoE
quelle
3

(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" :)

Warbo
quelle
2

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:

  1. Nehmen Sie eine Änderung vor
  2. Erstellen und testen Sie Ihre Änderung (im Idealfall automatisch)
  3. Wenn die Tests fehlschlagen, bedeutet dies, dass Sie etwas kaputt gemacht haben, das zuvor funktioniert hat
  4. Wenn die Tests erfolgreich sind, sollten Sie sicher sein, dass Ihre Änderung keine neuen Regressionen eingeführt hat (abhängig von der Testabdeckung).

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.

Es fördert die Idee, dass Code perfekt sein sollte und keine Bugs existieren sollten.
Es ist nicht ratsam, Unit-Tests auszudenken, die fehlschlagen werden

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.

Es hält Schreibgerätetests von vorn ab

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.

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.

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!

Justin
quelle
2

Die vorhandenen Antworten sind sicherlich gut, aber ich habe niemanden gesehen, der dieses grundlegende Missverständnis in der Frage angesprochen hat:

Zu jedem Zeitpunkt müssen alle Komponententests bestanden sein

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:

UPDATE my_table(
SET column_1 = 'MyValue'
WHERE id_column = 123;

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.

GalacticCowboy
quelle
0

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.

Michael Kay
quelle
Ich denke, was Sie als "externe Tests" bezeichnen, wird an anderer Stelle oft als "Integrationstest" bezeichnet.
GalacticCowboy
Ja, aber ich bin auf terminologische Unterschiede gestoßen. Für manche geht es beim Integrationstest eher um die bereitgestellte Software- / Hardware- / Netzwerkkonfiguration, während es sich um das externe Verhalten einer Software handelt, die Sie entwickeln.
Michael Kay
0

"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?

Jay
quelle
-7

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.

  • Ich habe eine Regel in meinem Kopf, dass jede Serie von drei Zahlen bestehen oder scheitern wird,
  • 2,4,6 ist ein Pass
  • Sie können Sätze von drei Zahlen auflisten, und ich werde Ihnen sagen, ob sie bestanden haben oder nicht.

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:

  • 4, 8, 12 & le; Bestehen
  • 20, 40, 60 & le; Bestehen
  • 2, 1004, 2006? Bestehen

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.

Scott
quelle
2
Wie ist es für die Frage relevant? Fehlgeschlagene Komponententests sind per Definition ein Hinweis auf ein Problem.
Frax
1
Sie absolut können Unit - Tests haben, benötigen Sie das System im Test einen Fehlermodus. Das ist nicht dasselbe, als wenn niemals ein Test fehlschlägt. Dies ist auch der Grund, warum TDD als "Rot-> Grün-> Refaktor" -Zyklus angegeben wird
Caleth,