Broken Old / Legacy Unit Tests


13

Ich arbeite für ein großes Unternehmen und bin für eine große Java-Anwendung mit Tausenden von Junit-Tests verantwortlich. Seit ich in diese Rolle gewechselt bin, gab es 200-300 defekte Tests (wahrscheinlich seit Jahren defekt). Die Tests sind alt und zerbrechlich und es gibt eine Menge Spaghetti-Abhängigkeiten, die normalerweise mit Live-Sandbox-Daten enden.

Mein Ziel ist es, dass die Tests zu 100% bestanden werden, damit wir die Fehler beim Komponententest beheben können. Ich kann dies jedoch erst tun, wenn ich mich mit den fehlerhaften Tests befasse. Ich habe nur ein sehr kleines Budget, da das Wartungsbudget hauptsächlich für den Support vorgesehen ist, aber mein Team hat die niedrig hängenden Fruchttests (hauptsächlich Konfigurations- / lokale Ressourcenprobleme) identifiziert und behoben, und wir haben nur 30-40 wirklich hässliche Tests.

Was sind einige Meinungen zu Best Practice? Ich denke nicht, dass die Tests wertvoll sind, aber ich weiß auch nicht, was sie testen oder warum sie nicht funktionieren, ohne sich einzuarbeiten, was Zeit und Geld kostet, die wir wahrscheinlich nicht haben.

Ich denke, wir sollten den Status der fehlerhaften Tests mit allem dokumentieren, was wir wissen, dann die fehlerhaften Tests entweder löschen oder vollständig ignorieren und einen Fehler / ein Arbeitselement mit niedrigerer Priorität eingeben, um sie zu untersuchen und zu beheben. Dann sind wir zu 100% und können die anderen Tests zu einem echten Gewinn machen. Wenn wir einen Wartungs-Refactoring-Fehler haben, können wir sie wieder aufnehmen.

Was wäre der beste Ansatz?

Bearbeiten: Ich denke, dies ist eine andere Frage als diese Frage, weil ich eine klare Richtung für die Tests habe, die wir in Zukunft schreiben sollten, aber ich habe das Erbe von fehlgeschlagenen Tests geerbt, bevor die große Anzahl aktueller Tests aussagekräftig wird.


1
Stimmen Sie definitiv zu, dass Sie 30-40 hässliche Tests loswerden sollten. "Wenn wir jedoch einen Wartungs / Umgestaltungsschub haben, können wir sie wieder aufnehmen", klingt das nach Wunschdenken. Ich bin mir nicht sicher, ob es einen wirklichen Vorteil hat, sie als Artikel mit niedriger Priorität zu dokumentieren, da solche Artikel die Angewohnheit haben, niemals in Aktion zu treten.
David Arno

1
Ich empfehle, dieses Buch zu lesen : Effektiv mit Legacy-Code arbeiten . Eine Buchempfehlung ist keine Antwort auf Ihre Frage, aber Sie finden dort viele gute Ratschläge zum Testen von Einheiten.

4
Dies mag ein Duplikat von etwas sein, aber es ist nicht diese Frage. Dabei geht es nicht darum, wie man das Schreiben fragiler Komponententests vermeidet, sondern wie man eine geerbte Codebasis mit bereits geschriebenen Komponententests verwaltet, die fehlschlagen.

1
Anscheinend haben Sie Ihre Lösung bereits gefunden.
Doc Brown

2
@gnat Ich stimme nicht zu. Aus persönlicher Erfahrung gibt es einen großen Unterschied zwischen "Etwas hat letzte Nacht viele meiner Komponententests zerstört" und "Ich habe eine Menge alten Code geerbt, bei dem Komponententests lange genug fehlgeschlagen sind, bis niemand weiß, warum." Eines ist ein Problem mit der aktuellen Entwicklung, eines ist ein Problem mit Legacy-Software. Hier sind zwei unterschiedliche Ansätze erforderlich. Die oberste Antwort auf die verknüpfte Frage bezieht sich nicht auf die Altaspekte.

Antworten:


17

Was ich tun würde, ist zuerst die Tests zu deaktivieren, die fehlschlagen und immer fehlgeschlagen sind.

Machen Sie es so, dass ein fehlgeschlagener Test von Bedeutung ist.

Wenn Sie Nachforschungen anstellen, können Sie möglicherweise Personen, die schon länger in Ihrem Unternehmen sind, nach ihnen fragen. Möglicherweise gibt es eine Menge Stammeswissen über sie, das Sie dokumentieren / erfassen können. Möglicherweise aus Ihren VCS-Protokollen. "Oh, dieser Test ist seit dem Upgrade auf X immer fehlgeschlagen" oder andere Informationen können hilfreich sein.

Sobald Sie wissen, welche Funktionalität getestet wurde, können Sie Folgendes feststellen:

  • Kümmern wir uns darum, dass dies getestet wird?
  • Wie wichtig ist es, dies zu testen

Und dann mach eine Prioritätenliste.

Wahrscheinlich ist nichts auf dieser Liste wichtig genug, um später mehr Zeit zu haben, da es schon seit Jahren ignoriert wird. Ich würde also nicht zu viel Zeit / Ressourcen aufwenden, um all diese kaputten Tests zu dokumentieren und zu analysieren.


1
Ich mag die Idee, die Tests im Vorfeld zu deaktivieren, aber eine konservative Umgebung könnte kleinere inkrementelle Schritte vorziehen. Ich nehme an, es hängt von Ihrer Firma ab?
Aaron Hall

1
@AaronHall - Ich denke, wenn Sie sich Ihre unmittelbaren Code-Änderungsbedürfnisse ansehen (Korrekturen und Verbesserungen) und alle damit verbundenen fehlerhaften Tests identifizieren, können Sie all diese einschalten, die Tests auswerten und korrigieren und Ihre Codierungsänderungen mit dem Verständnis vornehmen dass Tests entweder bestehen, repariert werden oder gelöscht werden.
JeffO

6

Ich würde folgendes tun:

  1. Versuchen Sie genau zu bestimmen, was die fehlgeschlagenen Tests zu validieren versuchen.

  2. Triage - Wenn einige Tests versuchen, unwichtige Dinge wie (einen alten) Zustand der Welt zu testen, löschen Sie sie. Wenn Sie feststellen, dass einige von ihnen versuchen, etwas Wichtiges zu validieren, versuchen Sie festzustellen, ob diese Tests dies korrekt durchführen. Wenn sie falsch testen, lassen Sie sie richtig testen.

  3. Beheben Sie jetzt, nachdem Sie gute Tests durchgeführt haben, alle Probleme mit Ihrem Produktionscode.

Denken Sie daran, dass jede Codezeile eine Verbindlichkeit darstellt, jedoch möglicherweise fälschlicherweise als Vermögenswert bewertet wird. Der deleteSchlüssel kann viel Wert für Ihr Unternehmen schaffen.


Eine Triage-Idee im Teamstil ist sehr schön!

Gute Ideen, aber OP hat bereits gesagt, dass er keine Ressourcen für umfangreiche Analysen hat, sodass er sie leider nicht verwenden kann.
TMN

Bei Triage geht es darum, begrenzte Ressourcen so zuzuteilen, dass sie den größten Wert schaffen. Hier ist ein relevanter Blog-Beitrag zum Thema Triage und Software: softwaretestingclub.com/profiles/blogs/…
Aaron Hall

5

200-300 gebrochene Tests (wahrscheinlich jahrelang gebrochen).

Autsch! Ich sah mich einmal einer ähnlichen Situation gegenüber, aber mit ungefähr 7 fehlgeschlagenen Tests, bei denen das Team anfing, die Tatsache zu ignorieren, dass sie monatelang aufgrund der "Always-Crunch" -Mentalität fehlgeschlagen waren.

Mein Ziel ist es, dass die Tests zu 100% bestanden werden, damit wir die Fehler beim Komponententest beheben können. Ich kann dies jedoch erst tun, wenn ich mich mit den fehlerhaften Tests befasst habe.

Ich war von einem ähnlichen Ziel besessen, obwohl ich nur ein Junior-Entwickler im Team war, weil ich einen Haufen bemerkte, bei dem im Laufe der Monate mehr Tests fehlschlugen. Ich wollte, dass wir diese von "Warnungen" in Build-Fehler verwandeln (vielleicht etwas unangenehm für den Rest des Teams).

Ich denke, wir sollten den Status der fehlerhaften Tests mit allem dokumentieren, was wir wissen, dann die fehlerhaften Tests entweder löschen oder vollständig ignorieren und einen Fehler / ein Arbeitselement mit niedrigerer Priorität eingeben, um sie zu untersuchen und zu beheben. Wir sind dann zu 100% und können die anderen Tests zu einem echten Gewinn machen. Wenn wir einen Wartungs-Refactoring-Fehler haben, können wir sie wieder aufgreifen.

Das sind auch meine Gedanken. Sie können alle diese fehlerhaften Tests vorübergehend deaktivieren und sie langsam aufrufen und im Laufe der Zeit beheben. Es ist wichtig, diese Korrekturen einzuplanen, wenn Sie sie für wirklich wichtig halten, auch wenn sie eine niedrige Priorität haben, da solche Elemente einfach nicht mehr repariert werden können. Mir ist es wichtig sicherzustellen, dass keine neuen Tests eingeführt werden, die fehlschlagen.

Wie jede Art von Warnung häufen sie sich schnell an, wenn sie den Build nicht abbrechen. Dies setzt eine solche Teamdynamik voraus, bei der die Gewohnheit, Warnungen zu ignorieren (in diesem Fall fehlgeschlagene Tests), schnell zu mehr Warnungen führen und die Versuchung verringern kann, diese Warnungen auf Null zu halten.

Ein sehr gewissenhaftes Team wird diese Probleme möglicherweise nicht haben und es vermeiden, neue Warnungen (neue Fehler in Tests) einzuführen. Es ist jedoch auf jeden Fall sicherer, etwas umsichtiger vorzugehen und eine Präventionsstrategie zu verfolgen, indem diese in Fehler umgewandelt werden, die vor dem Fehler behoben werden müssen Zusammenführungsprozess.

Mein Vorschlag ist also derselbe wie der Ihre (wenn auch nur eine starke Meinung - vielleicht kann dies ein wenig durch Metriken und eine wissenschaftlichere Antwort untermauert werden). Deaktivieren Sie diese alten Tests und setzen Sie sie in den Zeitplan, um sie schließlich zu beheben. Die erste Priorität besteht darin, sicherzustellen, dass sich dieses Problem nicht häuft und sich verschlimmert, indem sichergestellt wird, dass die derzeit erfolgreichen Tests letztendlich nicht ignoriert werden, wenn sie fehlschlagen.


4

In gewisser Weise hast du Glück. Es ist besser, Tests zu haben, die fehlschlagen und nicht fehlschlagen (sie warnen Sie zumindest davor, dass etwas nicht stimmt), als Tests, die bestanden werden und nicht bestanden werden (was Ihnen ein falsches Sicherheitsgefühl verleiht).
Natürlich, wenn Sie die erste haben, ist es sehr wahrscheinlich, dass Sie auch die zweite haben (also Tests, die bestanden werden, aber scheitern sollten).

Wie bereits erwähnt, deaktivieren Sie diese fehlgeschlagenen Tests zunächst, lassen Sie sie jedoch eine Meldung in Ihrem Testprotokoll ausdrucken, um sie ständig daran zu erinnern.
Aber Sie sollten auf jeden Fall die Ressourcen finden, um Ihre gesamte Testsuite zu durchsuchen, um die bestandenen und nicht bestandenen Tests zu finden und auszusortieren, da jede von ihnen bedeutet, dass Ihr Code einen Fehler enthält, den Sie derzeit nicht in Ihrem Code finden Testzyklen.

Wenn Sie diese dunkle Wolke verwenden, die über der Codebasis hängt, erhalten Sie möglicherweise ein Budget für eine vollständige Überprüfung Ihrer Tests, wenn Sie es richtig spielen und ihnen nicht einfach sagen, dass Sie der Meinung sind, dass einige Tests überprüft werden sollten, weil sie zu sein scheinen Schlagen Sie fehl, wenn dies nicht der Fall sein sollte. Sie können jedoch nicht sicher sein, dass Ihre Tests Fehler in Ihrem Code richtig erkennen.
Als ich das bei einer früheren Firma tat, habe ich für eine solche Überprüfung gearbeitet und festgestellt, dass Hunderte von Tests mit falschen Annahmen darüber geschrieben wurden, was der Code tun SOLLTE, was dazu führte, dass der Code (der mit denselben falschen Annahmen geschrieben wurde) die Tests bestanden hat, als sollte es wirklich nicht haben. Die Behebung dieses Problems löste so manchen bösen Eckfehler, der (obwohl die meisten nicht kritisch waren) einige wichtige Systeme zum Absturz bringen konnte.


3

Jeder fehlgeschlagene Komponententest sollte dazu führen, dass der Build abgebrochen wird. Gut, dass Sie es realisiert und sich dieses Ziel gesetzt haben. Der menschliche Geist kann kaum etwas vollkommeneres ignorieren als die Quelle eines andauernden Fehlalarms .

Werfen Sie diese Tests weg und schauen Sie nicht zurück. Wenn sie seit Jahren scheitern und bis jetzt noch nicht angegangen wurden, haben sie keine Priorität.

Was das Stammeswissen betrifft, sollten die Leute mit dem Stammeswissen die fehlgeschlagenen Tests bis jetzt behoben haben, wenn sie noch da sind. Wenn nicht, haben diese wiederum keine Priorität.

Wenn es kein Stammeswissen gibt, müssen Sie und Ihr Team die Logik übernehmen. Die fehlgeschlagenen Tests mögen eher irreführend als hilfreich sein - die Welt mag weitergegangen sein.

Erstellen Sie neue Tests, die relevant sind, und schreiben Sie großartigen Code.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.