it-swarm.com.de

Gibt es zu viele Unit-Tests?

Ich wurde beauftragt, Komponententests für eine vorhandene Anwendung zu schreiben. Nach Abschluss meiner ersten Datei habe ich 717 Zeilen Testcode für 419 Zeilen Originalcode.

Wird dieses Verhältnis unüberschaubar, wenn wir unsere Codeabdeckung erhöhen?

Mein Verständnis von Unit-Tests bestand darin, jede Methode in der Klasse zu testen, um sicherzustellen, dass jede Methode wie erwartet funktioniert. In der Pull-Anfrage stellte mein technischer Leiter jedoch fest, dass ich mich auf Tests auf höherer Ebene konzentrieren sollte. Er schlug vor, 4-5 Anwendungsfälle zu testen, die am häufigsten für die betreffende Klasse verwendet werden, anstatt jede Funktion ausführlich zu testen.

Ich vertraue dem Kommentar meines technischen Leiters. Er hat mehr Erfahrung als ich und er hat bessere Instinkte beim Entwerfen von Software. Aber wie schreibt ein Team aus mehreren Personen Tests für einen so mehrdeutigen Standard? Das heißt, woher kenne ich meine Kollegen und teile die gleiche Idee für "die häufigsten Anwendungsfälle"?

Für mich ist eine 100% ige Abdeckung durch Unit-Tests ein hohes Ziel, aber selbst wenn wir nur 50% erreichen würden, würden wir wissen, dass 100% dieser 50% abgedeckt waren. Andernfalls lässt das Schreiben von Tests für einen Teil jeder Datei viel Raum zum Betrügen.

143
user2954463

Ja, mit 100% Deckung schreiben Sie einige Tests, die Sie nicht benötigen. Leider ist der einzige zuverlässige Weg, um festzustellen, welche Tests Sie nicht benötigen, alle zu schreiben und dann etwa 10 Jahre zu warten, um festzustellen, welche nie fehlgeschlagen sind.

Das Aufrechterhalten vieler Tests ist normalerweise nicht problematisch. Viele Teams haben automatisierte Integrations- und Systemtests zusätzlich zu 100% Unit-Test-Abdeckung.

Sie befinden sich jedoch nicht in einer Testwartungsphase, sondern spielen Aufholjagd. Es ist viel besser, 100% Ihrer Klassen bei 50% Testabdeckung zu haben als 50% Ihrer Klassen bei 100% Testabdeckung, und Ihr Lead scheint zu versuchen, Sie dazu zu bringen, Ihre Zeit entsprechend zuzuweisen. Nachdem Sie diese Grundlinie erreicht haben, besteht der nächste Schritt normalerweise darin, in Dateien, die in Zukunft geändert werden, auf 100% zu drängen.

180
Karl Bielefeldt

Wenn Sie an großen Codebasen gearbeitet haben, die mit Test Driven Development erstellt wurden, wissen Sie bereits, dass es zu viele Komponententests geben kann. In einigen Fällen besteht der größte Teil des Entwicklungsaufwands darin, Tests mit geringer Qualität zu aktualisieren, die am besten als Invarianten-, Vorbedingungs- und Nachbedingungsprüfungen in den relevanten Klassen zur Laufzeit implementiert werden (dh Tests als Nebeneffekt eines Tests auf höherer Ebene) ).

Ein weiteres Problem ist die Erstellung von Designs mit schlechter Qualität unter Verwendung von frachtkultgetriebenen Designtechniken, die zu einer Vielzahl von zu testenden Dingen führen (mehr Klassen, Schnittstellen usw.). In diesem Fall scheint die Belastung darin zu liegen, den Testcode zu aktualisieren, aber das wahre Problem ist ein Design von schlechter Qualität.

68
Frank Hileman

Antworten auf Ihre Fragen

Gibt es zu viele Unit-Tests?

Sicher ... Sie könnten zum Beispiel mehrere Tests durchführen lassen, die auf den ersten Blick unterschiedlich zu sein scheinen, aber tatsächlich dasselbe testen (logischerweise von denselben Zeilen "interessanten" Anwendungscodes abhängig, der getestet wird).

Oder Sie könnten Interna Ihres Codes testen, die niemals nach außen auftauchen (d. H. Nicht Teil eines Schnittstellenvertrags sind), wo man darüber streiten könnte, ob dies überhaupt Sinn macht. Zum Beispiel den genauen Wortlaut interner Protokollnachrichten oder was auch immer.

Ich wurde beauftragt, Komponententests für eine vorhandene Anwendung zu schreiben. Nach Abschluss meiner ersten Datei habe ich 717 Zeilen Testcode für 419 Zeilen Originalcode.

Das kommt mir ganz normal vor. Ihre Tests verbrauchen zusätzlich zu den eigentlichen Tests viele Codezeilen für das Einrichten und Herunterfahren. Das Verhältnis kann sich verbessern oder nicht. Ich selbst bin ziemlich testlastig und investiere oft mehr Zeit und Zeit in die Tests als der eigentliche Code.

Wird dieses Verhältnis unüberschaubar, wenn wir unsere Codeabdeckung erhöhen?

Das Verhältnis berücksichtigt nicht so viel. Es gibt andere Eigenschaften von Tests, die dazu neigen, sie unüberschaubar zu machen. Wenn Sie regelmäßig eine ganze Reihe von Tests überarbeiten müssen, wenn Sie relativ einfache Änderungen an Ihrem Code vornehmen, sollten Sie sich die Gründe genau ansehen. Und das ist nicht, wie viele Zeilen Sie haben, sondern wie Sie sich der Codierung der Tests nähern.

Mein Verständnis von Unit-Tests bestand darin, jede Methode in der Klasse zu testen, um sicherzustellen, dass jede Methode wie erwartet funktioniert.

Das ist richtig für "Unit" -Tests im engeren Sinne. Hier ist "Einheit" so etwas wie eine Methode oder eine Klasse. Beim Testen von "Einheiten" wird nur eine bestimmte Codeeinheit getestet, nicht das gesamte System. Idealerweise würden Sie den gesamten Rest des Systems entfernen (mit Doppel oder so weiter).

In der Pull-Anfrage stellte mein technischer Leiter jedoch fest, dass ich mich auf Tests auf höherer Ebene konzentrieren sollte.

Dann sind Sie in die Falle geraten, anzunehmen, dass Menschen tatsächlich gemeint Unit-Tests sind, wenn sie gesagt Unit-Tests. Ich habe viele Programmierer getroffen, die "Unit Test" sagen, aber etwas ganz anderes bedeuten.

Er schlug vor, 4-5 Anwendungsfälle zu testen, die am häufigsten für die betreffende Klasse verwendet werden, anstatt jede Funktion ausführlich zu testen.

Sicher, wenn Sie sich nur auf die obersten 80% des wichtigen Codes konzentrieren, wird auch die Last reduziert ... Ich weiß zu schätzen, dass Sie Ihren Chef sehr schätzen, aber dies scheint mir nicht die optimale Wahl zu sein.

Für mich ist eine 100% ige Abdeckung durch Unit-Tests ein hohes Ziel, aber selbst wenn wir nur 50% erreichen würden, würden wir wissen, dass 100% dieser 50% abgedeckt waren.

Ich weiß nicht, was "Unit Test Coverage" ist. Ich gehe davon aus, dass Sie "Codeabdeckung" meinen, d. H., Dass nach dem Ausführen der Testsuite jede Codezeile (= 100%) mindestens einmal ausgeführt wurde.

Dies ist eine nette Baseball-Metrik, aber bei weitem nicht der beste Standard, für den man schießen kann. Nur Codezeilen auszuführen ist nicht das ganze Bild; Dies berücksichtigt beispielsweise keine unterschiedlichen Pfade durch komplizierte, verschachtelte Zweige. Es ist eher eine Metrik, die mit dem Finger auf zu wenig getestete Codeteile zeigt (offensichtlich stimmt etwas nicht, wenn eine Klasse eine Codeabdeckung von 10% oder 5% aufweist). Auf der anderen Seite sagt Ihnen eine 100% ige Abdeckung nicht, ob Sie genug oder richtig getestet haben.

Integrationstests

Es ärgert mich sehr, wenn die Leute heute standardmäßig ständig über unit Testen sprechen. Meiner Meinung nach (und meiner Erfahrung nach) ist unit Testen für Bibliotheken/APIs großartig; In eher geschäftsorientierten Bereichen (in denen wir über Anwendungsfälle wie in der vorliegenden Frage sprechen) sind sie nicht unbedingt die beste Option.

Für den allgemeinen Anwendungscode und im durchschnittlichen Geschäft (wo es wichtig ist, Geld zu verdienen, Termine einzuhalten und die Kundenzufriedenheit zu erfüllen, und Sie hauptsächlich Fehler vermeiden möchten, die entweder direkt im Gesicht des Benutzers liegen oder zu real Katastrophen - wir sprechen hier nicht von NASA-Raketenstarts), Integrations- oder Funktionstests sind viel nützlicher.

Diese gehen Hand in Hand mit verhaltensgesteuerter Entwicklung oder funktionsgesteuerter Entwicklung. Diese funktionieren per Definition nicht mit (strengen) Unit-Tests.

Um es kurz zu machen (ish), übt ein Integrations-/Funktionstest den gesamten Anwendungsstapel aus. In einer webbasierten Anwendung würde es sich wie ein Browser verhalten, der durch die Anwendung klickt (und nein, offensichtlich nicht haben Um so einfach zu sein, gibt es dafür sehr leistungsfähige Frameworks - check out http://cucumber.io für ein Beispiel).

Um Ihre letzten Fragen zu beantworten: Sie sorgen dafür, dass Ihr gesamtes Team eine hohe Testabdeckung hat, indem Sie sicherstellen, dass eine neue Funktion erst programmiert wird, nachdem ihr Funktionstest implementiert wurde und fehlgeschlagen ist. Und ja, das bedeutet alle Funktion. Dies garantiert Sie erhalten eine 100% ige (positive) Funktionsabdeckung. Es garantiert per Definition, dass eine Funktion Ihrer Anwendung niemals "verschwindet". Es garantiert keine 100% ige Codeabdeckung (wenn Sie beispielsweise negative Funktionen nicht aktiv programmieren, üben Sie Ihre Fehlerbehandlung/Ausnahmebehandlung nicht aus).

Es garantiert Ihnen keine fehlerfreie Anwendung. Natürlich möchten Sie Funktionstests für offensichtliche oder sehr gefährliche Fehlersituationen, falsche Benutzereingaben, Hacking (z. B. Sitzungsmanagement, Sicherheit usw.) usw. schreiben. Aber selbst das Programmieren der positiven Tests hat einen enormen Vorteil und ist mit modernen, leistungsstarken Frameworks durchaus machbar.

Feature-/Integrationstests haben offensichtlich ihre eigene Dose Würmer (z. B. Leistung; redundantes Testen von Frameworks von Drittanbietern; da Sie normalerweise keine Doubles verwenden, sind sie meiner Erfahrung nach auch schwieriger zu schreiben ...), aber ich ' d Nehmen Sie jeden Tag eine 100% positiv getestete Anwendung über eine 100% Code-Coverage-Unit-getestete Anwendung (keine Bibliothek!).

36
AnoE

Ja, es können zu viele Komponententests durchgeführt werden. Wenn Sie beispielsweise eine 100% ige Abdeckung mit Komponententests und keine Integrationstests haben, liegt ein klares Problem vor.

Einige Szenarien:

  1. Sie überarbeiten Ihre Tests auf eine bestimmte Implementierung. Dann müssen Sie Unit-Tests beim Refactor wegwerfen, ganz zu schweigen davon, wenn Sie die Implementierung ändern (ein sehr häufiger Schmerzpunkt bei der Durchführung von Leistungsoptimierungen).

    Ein ausgewogenes Verhältnis zwischen Komponententests und Integrationstests verringert dieses Problem, ohne dass eine signifikante Abdeckung verloren geht.

  2. Sie könnten für jedes Commit eine angemessene Deckung mit 20% der Tests haben, die Sie haben, und die restlichen 80% für die Integration oder zumindest separate Testdurchläufe übrig lassen. Die wichtigsten negativen Auswirkungen, die Sie in diesem Szenario sehen, sind langsame Änderungen, da Sie lange auf die Ausführung von Tests warten müssen.

  3. Sie ändern den Code zu stark, um ihn testen zu können. Ich habe zum Beispiel viel Missbrauch von IoC bei Komponenten gesehen, die niemals modifiziert werden müssen, oder es ist zumindest kostspielig und von geringer Priorität, sie zu verallgemeinern, aber die Leute investieren viel Zeit in die Verallgemeinerung und Umgestaltung, um sie durch Unit-Tests zu ermöglichen .

Ich stimme insbesondere dem Vorschlag zu, eine 100% ige Abdeckung von 100% der Dateien anstelle einer 100% igen Abdeckung von 50% der Dateien zu erreichen. Konzentrieren Sie Ihre anfänglichen Bemühungen auf die häufigsten positiven Fälle und die gefährlichsten negativen Fälle. Investieren Sie nicht zu viel in die Fehlerbehandlung und ungewöhnliche Pfade, nicht weil sie nicht wichtig sind, sondern weil Sie eine begrenzte Zeit und ein unendliches Testuniversum haben. Sie müssen also auf jeden Fall Prioritäten setzen.

25
Bruno Guardia

Beachten Sie, dass jeder Test sowohl Kosten als auch Nutzen hat. Nachteile sind:

  • ein Test muss geschrieben werden;
  • ein Test benötigt (normalerweise nur sehr wenig) Zeit, um ausgeführt zu werden.
  • ein Test muss mit dem Code verwaltet werden. Die Tests müssen sich ändern, wenn sich die zu testenden APIs ändern.
  • möglicherweise müssen Sie Ihr Design ändern, um einen Test zu schreiben (obwohl diese Änderungen normalerweise zum Besseren sind).

Wenn die Kosten den Nutzen überwiegen, ist es besser, einen Test nicht zu schreiben. Wenn beispielsweise die Funktionalität schwer zu testen ist, sich die API häufig ändert, die Korrektheit relativ unwichtig ist und die Wahrscheinlichkeit, dass der Test einen Fehler feststellt, gering ist, ist es wahrscheinlich besser, ihn nicht zu schreiben.

Wenn der Code für Ihr spezielles Verhältnis von Tests zu Code ausreichend logisch dicht ist, kann dieses Verhältnis gewährleistet werden. Es lohnt sich jedoch wahrscheinlich nicht, während einer typischen Anwendung ein so hohes Verhältnis beizubehalten.

19

Ja, es gibt zu viele Unit-Tests.

Während das Testen gut ist, ist jeder Komponententest:

  • Eine potenzielle Wartungslast, die eng mit der API verbunden ist

  • Zeit, die für etwas anderes aufgewendet werden könnte

  • Ein Stück Zeit in der Unit Test Suite
  • Möglicherweise wird kein wirklicher Wert hinzugefügt, da es sich tatsächlich um ein Duplikat eines anderen Tests handelt, bei dem die Wahrscheinlichkeit gering ist, dass ein anderer Test bestanden wird und dieser Test fehlschlägt.

Es ist ratsam, eine 100% ige Codeabdeckung anzustreben, aber dies bedeutet keineswegs eine Reihe von Tests, von denen jeder unabhängig eine 100% ige Codeabdeckung für einen bestimmten Einstiegspunkt (Funktion/Methode/Aufruf usw.) bietet.

Angesichts der Schwierigkeit, eine gute Abdeckung zu erreichen und Fehler auszutreiben, ist es wahrscheinlich, dass es so etwas wie "falsche Komponententests" und "zu viele Komponententests" gibt.

Pragmatik für die meisten Codes zeigt an:

  1. Stellen Sie sicher, dass Sie eine 100% ige Abdeckung der Einstiegspunkte haben (alles wird irgendwie getestet), und versuchen Sie, eine nahezu 100% ige Codeabdeckung der fehlerfreien Pfade zu erreichen.

  2. Testen Sie alle relevanten Min/Max-Werte oder Größen

  3. Testen Sie alles, was Sie für einen lustigen Sonderfall halten, insbesondere "ungerade" Werte.

  4. Wenn Sie einen Fehler finden, fügen Sie einen Komponententest hinzu, der diesen Fehler aufgedeckt hätte, und überlegen Sie, ob ähnliche Fälle hinzugefügt werden sollten.

Beachten Sie für komplexere Algorithmen auch:

  1. Führen Sie einige Massentests für mehr Fälle durch.
  2. Vergleich des Ergebnisses mit einer Brute-Force-Implementierung und Überprüfung der Invarianten.
  3. Verwendung einer Methode zur Erstellung zufälliger Testfälle und zur Überprüfung auf Brute-Force- und Post-Bedingungen einschließlich Invarianten.

Überprüfen Sie beispielsweise einen Sortieralgorithmus mit einer zufälligen Eingabe, und überprüfen Sie, ob die Daten am Ende durch Scannen sortiert sind.

Ich würde sagen, Ihr technischer Leiter schlägt "Minimal Bare Ass" -Tests vor. Ich biete 'Qualitätsprüfungen mit dem höchsten Wert' an und dazwischen liegt ein Spektrum.

Vielleicht weiß Ihr Senior, dass die Komponente, die Sie bauen, in ein größeres Teil eingebettet und die Einheit bei der Integration gründlicher getestet wird.

Die wichtigste Lektion besteht darin, Tests hinzuzufügen, wenn Fehler gefunden werden. Was mich zu meiner besten Lektion über die Entwicklung von Unit-Tests führt:

Konzentrieren Sie sich auf Einheiten, nicht auf Untereinheiten. Wenn Sie eine Einheit aus Untereinheiten aufbauen, schreiben Sie sehr grundlegende Tests für die Untereinheiten, bis sie plausibel sind, und erzielen Sie eine bessere Abdeckung, indem Sie Untereinheiten über ihre Steuereinheiten testen.

Wenn Sie also einen Compiler schreiben und eine Symboltabelle schreiben müssen (sagen wir). Starten Sie die Symboltabelle mit einem Basistest und arbeiten Sie dann an dem Deklarationsparser, der die Tabelle füllt. Fügen Sie der Symboltabelle "Standalone" nur weitere Tests hinzu, wenn Sie darin Fehler finden. Andernfalls erhöhen Sie die Abdeckung durch Unit-Tests auf dem Deklarationsparser und später auf dem gesamten Compiler.

Das ist das Beste für Geld (ein Test des Ganzen besteht darin, mehrere Komponenten zu testen) und lässt mehr Kapazität für Neugestaltung und Verfeinerung, da nur die "äußere" Schnittstelle für Tests verwendet wird, die tendenziell stabiler sind.

In Verbindung mit Vorbedingungen für Debug-Code-Tests und Nachbedingungen, einschließlich Invarianten auf allen Ebenen, erhalten Sie maximale Testabdeckung durch minimale Testimplementierung.

13
Persixty

Erstens ist es nicht unbedingt ein Problem, mehr Zeilen Test als Produktionscode zu haben. Testcode ist (oder sollte) linear und leicht zu verstehen - seine notwendige Komplexität ist sehr, sehr gering, unabhängig davon, ob es sich um den Produktionscode handelt oder nicht. Wenn sich das Komplexität der Tests dem des Produktionscodes nähert, haben Sie wahrscheinlich ein Problem.

Ja, es ist möglich, dass zu viele Komponententests durchgeführt werden. Ein einfaches Gedankenexperiment zeigt, dass Sie weiterhin Tests hinzufügen können, die keinen zusätzlichen Wert bieten, und dass all diese hinzugefügten Tests zumindest einige Refactorings verhindern können.

Der Rat, nur die häufigsten Fälle zu testen, ist meiner Meinung nach fehlerhaft. Diese können als Rauchtests dienen, um Zeit für Systemtests zu sparen, aber die wirklich wertvollen Tests erfassen Fälle, die im gesamten System schwer durchzuführen sind. Beispielsweise kann eine kontrollierte Fehlerinjektion von Speicherzuordnungsfehlern verwendet werden, um Wiederherstellungspfade auszuüben, die ansonsten von völlig unbekannter Qualität sein könnten. Oder übergeben Sie Null als einen Wert, von dem Sie wissen, dass er als Divisor verwendet wird (oder als negative Zahl, die quadratisch ist), und stellen Sie sicher, dass Sie keine unbehandelte Ausnahme erhalten.

Die nächst wertvollsten Tests sind solche, die die extremen Grenzen oder Grenzpunkte ausüben. Beispielsweise sollte eine Funktion, die (1-basierte) Monate des Jahres akzeptiert, mit 0, 1, 12 und 13 getestet werden, damit Sie wissen, dass die gültigen und ungültigen Übergänge an der richtigen Stelle sind. Es ist übertrieben zu testen, auch 2..11 für diese Tests zu verwenden.

Sie befinden sich in einer schwierigen Position, da Sie Tests für vorhandenen Code schreiben müssen. Es ist einfacher, die Edge-Fälle zu identifizieren, wenn Sie den Code schreiben (oder gerade schreiben).

3
Toby Speight

Mein Verständnis von Unit-Tests bestand darin, jede Methode in der Klasse zu testen, um sicherzustellen, dass jede Methode wie erwartet funktioniert.

Dieses Verständnis ist falsch.

Unit-Tests verifizieren das Verhalten des zu testende Unit.

In diesem Sinne ist eine Einheit nicht unbedingt "eine Methode in einer Klasse". Ich mag die Definition einer Einheit von Roy Osherove in The Art of Unit Testing:

Eine Einheit ist der gesamte Produktionscode, der denselben Grund zur Änderung hat.

Basierend darauf sollte ein Unit-Test jedes gewünschte Verhalten Ihres Codes überprüfen. Wo der "Wunsch" mehr oder weniger aus den Anforderungen genommen wird.


In der Pull-Anfrage stellte mein technischer Leiter jedoch fest, dass ich mich auf Tests auf höherer Ebene konzentrieren sollte.

Er hat recht, aber anders als er denkt.

Aus Ihrer Frage verstehe ich, dass Sie der "engagierte Tester" in diesem Projekt sind.

Das große Missverständnis ist, dass er erwartet, dass Sie Unit-Tests schreiben (im Gegensatz zu "Test mit einem Unit-Test-Framework"). Das Schreiben von ynit-Tests ist das Verantwortung der Entwickler, nicht die Tester (in einer idealen Welt, ich weiß ...). Andererseits haben Sie diese Frage mit TDD markiert, was genau dies impliziert.

Ihre Aufgabe als Tester ist es, Modul- und/oder Anwendungstests zu schreiben (oder manuell auszuführen). Und diese Art von Tests sollte hauptsächlich sicherstellen, dass alle Einheiten reibungslos zusammenarbeiten. Das heißt, Sie müssen Ihre Testfälle so auswählen, dass jede Einheit mindestens einmal ausgeführt ist. Und diese Prüfung läuft. Das tatsächliche Ergebnis ist weniger wichtig, da es sich mit zukünftigen Anforderungen ändern kann.

Um die Dump-Automobile-Analogie noch einmal zu betonen: Wie viele Tests werden mit einem Auto am Ende der Montagelinie durchgeführt? Genau eins: Es muss alleine zum Parkplatz fahren ...

Der Punkt hier ist:

Wir müssen uns dieses Unterschieds zwischen "Unit-Tests" und "Test automatisiert mit einem Unit-Test-Framework" bewusst sein.


Für mich ist eine 100% ige Abdeckung durch Unit-Tests ein hohes Ziel, aber selbst wenn wir nur 50% erreichen würden, würden wir wissen, dass 100% dieser 50% abgedeckt waren.

Unit Tests sind ein Sicherheitsnetz. Sie geben Ihnen Vertrauen in Refactor Ihren Code, um technische Schulden zu reduzieren oder neues Verhalten hinzuzufügen, ohne befürchten zu müssen, bereits implementiertes Verhalten zu brechen.

Sie benötigen keine 100% ige Codeabdeckung.

Sie benötigen jedoch eine 100% ige Verhaltensabdeckung. (Ja, Codeabdeckung und Verhaltensabdeckung korrelieren irgendwie, aber sie sind deswegen nicht identisch.)

Wenn Sie weniger als 100% Verhaltensabdeckung haben, bedeutet ein erfolgreicher Lauf Ihrer Testsuite nichts, da Sie möglicherweise einen Teil des nicht getesteten Verhaltens geändert haben. Und Sie werden von Ihrem Kunden am Tag nach der Veröffentlichung Ihrer Veröffentlichung bemerkt ...


Fazit

Nur wenige Tests sind besser als kein Test. Ohne Zweifel!

Aber es gibt nicht zu viele Unit-Tests.

Dies liegt daran, dass jeder Komponententest ein einzelne Erwartung über die Codes Verhalten überprüft. Und Sie können nicht mehr Komponententests schreiben, als Sie von Ihrem Code erwarten. Und ein Loch in Ihrem Sicherheitsgurt kann dazu führen, dass unerwünschte Änderungen das Produktionssystem beschädigen.

3
Timothy Truckle

Absolut ja. Ich war SDET für ein großes Softwareunternehmen. Unser kleines Team musste Testcode pflegen, der früher von einem viel größeren Team verarbeitet wurde. Darüber hinaus hatte unser Produkt einige Abhängigkeiten, die ständig zu Änderungen führten, was für uns eine ständige Wartung der Tests bedeutet. Wir hatten nicht die Möglichkeit, die Teamgröße zu erhöhen, deshalb mussten wir Tausende der weniger wertvollen Tests wegwerfen, wenn sie fehlschlugen. Andernfalls könnten wir nie mit den Mängeln Schritt halten.

Bevor Sie dies als bloßes Managementproblem abtun, sollten Sie bedenken, dass viele Projekte in der realen Welt unter Personalabbau leiden, wenn sie sich dem Legacy-Status nähern. Manchmal passiert es sogar gleich nach der ersten Veröffentlichung.

2
mrog

Es ist nicht unbedingt ein Problem, mehr Testcodezeilen als Produktcode zu haben, vorausgesetzt, Sie überarbeiten Ihren Testcode, um das Kopieren und Einfügen zu vermeiden.

Ein Problem besteht darin, Tests zu haben, die Spiegel Ihrer Implementierung sind und keine geschäftliche Bedeutung haben - zum Beispiel Tests, die mit Mocks und Stubs geladen sind und nur behaupten, dass eine Methode eine andere Methode aufruft.

Ein gutes Zitat im "warum die meisten Unit-Tests Verschwendung sind" Papier ist, dass Unit-Tests ein "breites, formales, unabhängiges Orakel der Korrektheit und ... des zuordenbaren Geschäftswerts" haben sollten.

1
wrschneider

Eine Sache, die ich nicht erwähnt habe, ist, dass Ihre Tests schnell und einfach sein müssen, damit jeder Entwickler sie jederzeit ausführen kann.

Sie möchten nicht in die Quellcodeverwaltung einchecken und mindestens eine Stunde (abhängig von der Größe Ihrer Codebasis) warten müssen, bevor die Tests abgeschlossen sind, um festzustellen, ob Ihre Änderung etwas kaputt gemacht hat - Sie möchten dies tun können Ihren eigenen Computer, bevor Sie in die Quellcodeverwaltung einchecken (oder zumindest bevor Sie Ihre Änderungen vornehmen). Idealerweise sollten Sie Ihre Tests mit einem einzigen Skript oder einem Tastendruck ausführen können.

Und wenn Sie diese Tests lokal ausführen, möchten Sie, dass sie schnell ausgeführt werden - in der Größenordnung von Sekunden. Wenn Sie langsamer fahren, werden Sie versucht sein, sie nicht genug oder überhaupt nicht auszuführen.

Es könnte also ein Problem sein, so viele Tests zu haben, dass sie alle Minuten dauern, oder ein paar übermäßig komplexe Tests.

0
mmathis