Ist es sinnvoll, Tests für Legacy-Code zu schreiben, wenn keine Zeit für ein vollständiges Refactoring bleibt?

72

Normalerweise versuche ich, den Ratschlägen des Buches Working Effectively with Legacy Cod e zu folgen . Ich unterbreche Abhängigkeiten, verschiebe Teile des Codes in @VisibleForTesting public staticMethoden und in neue Klassen, um den Code (oder zumindest einen Teil davon) testbar zu machen. Und ich schreibe Tests, um sicherzustellen, dass ich beim Ändern oder Hinzufügen neuer Funktionen nichts kaputt mache.

Ein Kollege sagt, dass ich das nicht tun soll. Seine Argumentation:

  • Der ursprüngliche Code funktioniert möglicherweise überhaupt nicht richtig. Und das Schreiben von Tests macht zukünftige Korrekturen und Änderungen schwieriger, da Entwickler die Tests auch verstehen und modifizieren müssen.
  • Wenn es sich um GUI-Code mit einer gewissen Logik handelt (z. B. ~ 12 Zeilen, 2-3 if / else-Block), ist ein Test die Mühe nicht wert, da der Code zu trivial ist, um damit zu beginnen.
  • Ähnliche schlechte Muster könnten auch in anderen Teilen der Codebasis existieren (was ich noch nicht gesehen habe, ich bin ziemlich neu); es wird einfacher sein, sie alle in einem großen Refactoring aufzuräumen. Das Herausziehen von Logik könnte diese zukünftige Möglichkeit untergraben.

Sollte ich vermeiden, prüfbare Teile herauszunehmen und Tests zu schreiben, wenn wir keine Zeit für eine vollständige Überarbeitung haben? Gibt es einen Nachteil, den ich berücksichtigen sollte?

is4
quelle
29
Scheint, als würde Ihr Kollege nur Ausreden vorbringen, weil er nicht so arbeitet. Menschen verhalten sich manchmal so, weil sie zu hartnäckig sind, um ihre Verhaltensweise zu ändern.
Doc Brown
3
was als ein Fehler von anderen Teilen des Codes angeführt wird , klassifiziert werden kann , sollte es in eine Funktion drehen
Freak Ratsche
1
Das einzige gute Argument dagegen ist, dass Ihr Refactoring selbst neue Fehler verursachen könnte, wenn Sie etwas falsch gelesen / falsch kopiert haben. Aus diesem Grund kann ich die Version, die sich derzeit in der Entwicklung befindet, überarbeiten und nach Herzenslust korrigieren. Alle Korrekturen früherer Versionen sind jedoch mit einer viel höheren Hürde verbunden und werden möglicherweise nicht genehmigt, wenn es sich seitdem "nur" um kosmetische / strukturelle Aufräumarbeiten handelt Das Risiko übersteigt den potenziellen Gewinn. Kennen Sie Ihre lokale Kultur - nicht nur die Idee eines Kuhkünstlers - und haben Sie EXTREM starke Gründe, bevor Sie etwas anderes tun.
Keshlam
6
Der erste Punkt ist irgendwie komisch - "Teste es nicht, es könnte fehlerhaft sein." Nun ja? Dann ist es gut zu wissen, dass - entweder wir wollen das beheben oder wir wollen nicht, dass jemand das tatsächliche Verhalten so ändert, wie es einige Design-Spezifikationen sagten. In beiden Fällen ist das Testen (und Ausführen der Tests in einem automatisierten System) von Vorteil.
Christopher Creutzig
3
Zu oft ist das "eine große Umgestaltung", das bald stattfinden wird und das alle Übel heilt, ein Mythos, der von denen erfunden wird, die einfach Dinge, die sie für langweilig halten (Tests schreiben), in die ferne Zukunft verschieben wollen. Und falls es jemals Realität werden sollte, werden sie es ernsthaft bedauern, dass es so groß geworden ist!
Julia Hayward

Antworten:

100

Hier ist mein persönlicher unwissenschaftlicher Eindruck: Alle drei Gründe klingen nach weit verbreiteten, aber falschen kognitiven Illusionen.

  1. Sicher, der vorhandene Code könnte falsch sein. Es könnte auch richtig sein. Da die Anwendung als Ganzes für Sie von Wert zu sein scheint (andernfalls würden Sie sie einfach verwerfen), sollten Sie bei Fehlen spezifischerer Informationen davon ausgehen, dass sie überwiegend richtig ist. "Das Schreiben von Tests macht die Sache schwieriger, weil insgesamt mehr Code involviert ist" ist eine vereinfachte und sehr falsche Einstellung.
  2. In jedem Fall müssen Sie Ihre Bemühungen um Überarbeitung, Prüfung und Verbesserung dort einsetzen, wo sie mit geringstem Aufwand den größten Mehrwert bringen. GUI-Unterprogramme zur Formatierung von Werten haben häufig nicht die höchste Priorität. Aber etwas nicht zu testen, weil "es ist einfach" auch eine sehr falsche Einstellung ist. Praktisch alle schwerwiegenden Fehler sind begangen, weil die Leute dachten, sie hätten etwas besser verstanden als sie es tatsächlich taten.
  3. "Wir werden es in Zukunft auf einen Schlag schaffen", ist ein netter Gedanke. Normalerweise bleibt der große Schlag fest in der Zukunft, während in der Gegenwart nichts passiert. Ich bin fest davon überzeugt, dass "langsam und stetig das Rennen gewinnt".
Kilian Foth
quelle
23
+1 für "Praktisch alle schwerwiegenden Fehler sind begangen, weil die Leute dachten, sie hätten etwas besser verstanden als sie tatsächlich verstanden haben."
Rem
Zu Punkt 1 - mit BDD sind die Tests selbst dokumentierend ...
Robbie Dee
2
Wie @ guillaume31 hervorhebt, zeigt ein Teil des Werts von Schreibtests, wie der Code tatsächlich funktioniert - was möglicherweise den Spezifikationen entspricht oder nicht. Aber es könnte die Spezifikation sein, die "falsch" ist: Die Geschäftsanforderungen haben sich möglicherweise geändert und der Code spiegelt die neuen Anforderungen wider, die Spezifikation jedoch nicht. Die bloße Annahme, dass der Code "falsch" ist, ist zu einfach (siehe Punkt 1). Und wieder werden die Tests Ihnen sagen, was der Code tatsächlich tut und nicht, was jemand denkt / sagt (siehe Punkt 2).
David
Selbst wenn Sie nur einen Schlag ausführen, müssen Sie den Code verstehen. Tests helfen Ihnen dabei, unerwartetes Verhalten zu erkennen, auch wenn Sie nicht umgestalten, sondern umschreiben (und wenn Sie umgestalten, stellen Sie sicher, dass Ihr Refactoring das bisherige Verhalten nicht beeinträchtigt - oder nur dort, wo es unterbrochen werden soll). Fühlen Sie sich frei zu integrieren oder nicht - wie Sie es wünschen.
Frank Hopkins
50

Ein paar Gedanken:

Wenn Sie älteren Code überarbeiten, spielt es keine Rolle, ob einige der Tests, die Sie schreiben, den idealen Spezifikationen widersprechen. Was zählt, ist, dass sie das aktuelle Verhalten des Programms testen . Beim Refactoring geht es darum, winzige isofunktionale Schritte zu unternehmen, um den Code sauberer zu machen. Sie möchten sich nicht auf Bugfixes einlassen, während Sie umgestalten. Außerdem, wenn Sie einen offensichtlichen Bug entdecken, geht dieser nicht verloren. Sie können jederzeit einen Regressionstest schreiben und diesen vorübergehend deaktivieren oder eine Bugfix-Aufgabe für später in Ihr Backlog einfügen. Eins nach dem Anderen.

Ich bin damit einverstanden, dass reiner GUI-Code schwer zu testen ist und möglicherweise nicht für Refactoring im Stil " Effektiv arbeiten ... " geeignet ist. Dies bedeutet jedoch nicht, dass Sie kein Verhalten extrahieren sollten, das nichts mit der GUI-Ebene zu tun hat, und den extrahierten Code testen sollten. Und "12 Zeilen, 2-3 if / else-Block" ist nicht trivial. Jeder Code mit mindestens ein bisschen Bedingungslogik sollte getestet werden.

Nach meiner Erfahrung sind große Umbauten nicht einfach und funktionieren nur selten. Wenn Sie sich keine genauen, winzigen Ziele setzen, besteht ein hohes Risiko, dass Sie sich auf eine endlose, haarsträubende Überarbeitung einlassen, bei der Sie am Ende nie auf den Beinen landen. Je größer die Veränderung ist, desto größer ist das Risiko, dass Sie etwas kaputtmachen, und desto mehr Schwierigkeiten haben Sie, herauszufinden, wo Sie versagt haben.

Mit kleinen Ad-hoc-Nachbesserungen die Dinge immer besser zu machen, bedeutet nicht, "zukünftige Möglichkeiten zu untergraben", sondern sie zu aktivieren - den sumpfigen Boden zu festigen, auf dem Ihre Anwendung liegt. Sie sollten es auf jeden Fall tun.

guillaume31
quelle
5
+1 für "Tests, die Sie schreiben, testen Sie das aktuelle Verhalten des Programms "
David
17

Betreff: "Der ursprüngliche Code funktioniert möglicherweise nicht richtig" - das bedeutet nicht, dass Sie das Verhalten des Codes ändern, ohne sich Gedanken über die Auswirkungen zu machen. Bei anderen Codes kann es sich um fehlerhaftes Verhalten oder um Nebenwirkungen der aktuellen Implementierung handeln. Die Testabdeckung der vorhandenen Anwendung sollte die spätere Umgestaltung erleichtern, da Sie auf diese Weise herausfinden können, wenn Sie versehentlich etwas kaputt gemacht haben. Sie sollten zuerst die wichtigsten Teile testen.

Rory Hunter
quelle
Leider wahr. Wir haben ein paar offensichtliche Fehler, die sich in Randfällen manifestieren, die wir nicht beheben können, weil unser Kunde Konsistenz gegenüber Korrektheit bevorzugt. (Sie werden verursacht, weil der Code für die Datenerfassung Dinge
zulässt,
14

Kilians Antwort deckt die wichtigsten Aspekte ab, aber ich möchte auf die Punkte 1 und 3 eingehen.

Wenn ein Entwickler Code ändern (umgestalten, erweitern, debuggen) möchte, muss er ihn verstehen. Sie muss sicherstellen, dass sich ihre Änderungen genau auf das von ihr gewünschte Verhalten auswirken (nichts im Falle von Refactoring) und nichts anderes.

Wenn es Tests gibt, muss sie die Tests natürlich auch verstehen. Gleichzeitig sollten die Tests ihr helfen, den Hauptcode zu verstehen, und die Tests sind ohnehin viel einfacher zu verstehen als der Funktionscode (es sei denn, es handelt sich um schlechte Tests). Und die Tests zeigen, was sich am Verhalten des alten Codes geändert hat. Selbst wenn der ursprüngliche Code falsch ist und der Test das falsche Verhalten überprüft, ist dies immer noch ein Vorteil.

Dies setzt jedoch voraus, dass die Tests als Tests für bereits vorhandenes Verhalten und nicht als Spezifikation dokumentiert werden.

Einige Gedanken auch zu Punkt 3: Zusätzlich zu der Tatsache, dass der "Big Swoop" selten tatsächlich auftritt, gibt es noch eine andere Sache: Es ist eigentlich nicht einfacher. Um einfacher zu sein, müssten mehrere Bedingungen zutreffen:

  • Das zu überarbeitende Antimuster muss leicht zu finden sein. Sind alle Ihre Singletons benannt XYZSingleton? Wird ihr Instanz-Getter immer aufgerufen getInstance()? Und wie findest du deine zu tiefen Hierarchien? Wie suchst du nach deinen Gottobjekten? Diese erfordern eine Codemetrikanalyse und eine manuelle Überprüfung der Metriken. Oder du stolperst einfach über sie, während du arbeitest, wie du es getan hast.
  • Das Refactoring muss mechanisch sein. In den meisten Fällen ist es schwierig, den vorhandenen Code so gut zu verstehen, dass man weiß, wie man ihn ändert. Nochmals Singletons: Wenn der Singleton nicht mehr vorhanden ist, wie erhalten Sie die erforderlichen Informationen für die Benutzer? Es bedeutet oft, die lokale Anrufgrafik zu verstehen, damit Sie wissen, woher Sie die Informationen beziehen können. Was ist nun einfacher? Suchen Sie die zehn Singletons in Ihrer App, verstehen Sie die Verwendung der einzelnen Singletons (was dazu führt, dass Sie 60% der Codebasis verstehen müssen), und ziehen Sie sie heraus. Oder nehmen Sie den Code, den Sie bereits verstehen (weil Sie gerade daran arbeiten) und rippen Sie die Singletons heraus, die dort verwendet werden? Wenn das Refactoring nicht so mechanisch ist, dass es nur wenig oder gar keine Kenntnisse des umgebenden Codes erfordert, kann es nicht gebündelt werden.
  • Das Refactoring muss automatisiert werden. Dies ist etwas meinungsbasiert, aber hier geht. Ein bisschen Refactoring macht Spaß und ist befriedigend. Viele Umbauten sind mühsam und langweilig. Wenn Sie den Code, an dem Sie gerade gearbeitet haben, in einem besseren Zustand belassen, erhalten Sie ein angenehmes, warmes Gefühl, bevor Sie mit interessanteren Dingen fortfahren. Wenn Sie versuchen, eine ganze Codebasis umzugestalten, sind Sie frustriert und verärgert über die idiotischen Programmierer, die sie geschrieben haben. Wenn Sie ein großes Swoop-Refactoring durchführen möchten, muss es weitgehend automatisiert werden, um die Frustration zu minimieren. Dies ist in gewisser Weise eine Verschmelzung der ersten beiden Punkte: Sie können das Refactoring nur automatisieren, wenn Sie den fehlerhaften Code automatisch finden (dh leicht zu finden) und das Ändern (dh mechanisch) automatisieren können.
  • Allmähliche Verbesserungen sorgen für ein besseres Geschäftsmodell. Das große Swoop-Refactoring ist unglaublich störend. Wenn Sie einen Code umgestalten, geraten Sie ausnahmslos in Zusammenführungskonflikte mit anderen Personen, die daran arbeiten, da Sie die Methode, die sie geändert haben, in fünf Teile aufteilen. Wenn Sie einen angemessen großen Code umgestalten, kommt es zu Konflikten mit einigen wenigen Personen (1-2, wenn Sie die 600-Zeilen-Megafunktion aufteilen, 2-4, wenn Sie das Gott-Objekt auflösen, 5, wenn Sie den Singleton aus einem Modul herausreißen ), aber Sie hätten diese Konflikte ohnehin wegen Ihrer Hauptänderungen gehabt. Wenn Sie ein Codebasis-weites Refactoring durchführen, besteht ein Konflikt mit allen Beteiligten. Ganz zu schweigen davon, dass es einige Entwickler tagelang zusammenhält. Durch die schrittweise Verbesserung dauert jede Code-Änderung etwas länger. Dies macht es vorhersehbarer und es gibt keinen so sichtbaren Zeitraum, in dem nichts passiert, außer aufräumen.
Sebastian Redl
quelle
12

In einigen Unternehmen gibt es eine Kultur, in der Entwickler sich zurückhalten, Code zu verbessern, der keinen direkten Mehrwert bietet, z. B. neue Funktionen.

Ich predige wahrscheinlich zu den hier Konvertierten, aber das ist eindeutig eine falsche Wirtschaft. Sauberer und präziser Code kommt nachfolgenden Entwicklern zugute. Es ist nur so, dass die Amortisation nicht sofort ersichtlich ist.

Ich persönlich unterschreibe das Pfadfinderprinzip, aber andere (wie Sie gesehen haben) nicht.

Software leidet jedoch unter Entropie und baut technische Schulden auf. Frühere Entwickler, die wenig Zeit hatten (oder vielleicht nur faul oder unerfahren waren), haben möglicherweise suboptimale Buggy-Lösungen gegenüber gut gestalteten Lösungen implementiert. Obwohl es wünschenswert erscheinen mag, diese zu überarbeiten, riskieren Sie, neue Fehler in den (für die Benutzer ohnehin) funktionierenden Code einzufügen.

Einige Änderungen sind risikoärmer als andere. Wenn ich zum Beispiel arbeite, gibt es in der Regel viele duplizierte Codes, die mit minimaler Auswirkung sicher in eine Unterroutine ausgelagert werden können.

Letztendlich müssen Sie ein Urteil darüber fällen, wie weit Sie das Refactoring bringen, aber es ist zweifellos sinnvoll, automatisierte Tests hinzuzufügen, wenn diese noch nicht existieren.

Robbie Dee
quelle
2
Ich stimme im Prinzip vollkommen zu, aber in vielen Unternehmen kommt es auf Zeit und Geld an. Wenn der Teil "Aufräumen" nur ein paar Minuten dauert, ist das in Ordnung, aber sobald die Schätzung für das Aufräumen größer wird (für eine Definition von "groß"), müssen Sie, die Person, die die Kodierung vornimmt, diese Entscheidung an Ihren Chef delegieren oder Projektmanager. Es ist nicht Ihre Aufgabe, über den Wert dieser Zeit zu entscheiden. Die Arbeit an Bugfix X oder neuer Funktion Y hat möglicherweise einen viel höheren Wert für das Projekt / die Firma / den Kunden.
ozz
2
Möglicherweise sind Sie sich auch größerer Probleme nicht bewusst, wie der Verschrottung des Projekts in 6 Monaten oder einfach, dass das Unternehmen Ihre Zeit mehr schätzt (z. B. Sie tun etwas, das es für wichtiger hält, und jemand anderes kann die Refeactoring-Arbeiten ausführen). Refactoring-Arbeiten können sich auch auf das Testen auswirken. Wird ein großes Refactoring eine vollständige Testregression auslösen? Verfügt das Unternehmen über Ressourcen, die es dafür bereitstellen kann?
ozz
Ja, wie Sie bereits angesprochen haben, gibt es unzählige Gründe, warum größere Code-Eingriffe eine gute Idee sein können oder nicht: andere Entwicklungsprioritäten, Lebensdauer der Software, Testressourcen, Entwicklererfahrung, Kopplung, Veröffentlichungszyklus, Vertrautheit mit dem Code Basis, Dokumentation, Missionskritikalität, Unternehmenskultur usw. usw. Es ist ein Urteilsspruch
Robbie Dee
4

Nach meiner Erfahrung funktioniert eine Art Charakterisierungstest gut. Es bietet Ihnen relativ schnell eine breite, aber nicht sehr spezifische Testabdeckung, kann jedoch für GUI-Anwendungen schwierig zu implementieren sein.

Ich würde dann Komponententests für Teile schreiben, die Sie ändern möchten, und dies jedes Mal, wenn Sie eine Änderung vornehmen möchten, wodurch sich die Abdeckung der Komponententests mit der Zeit erhöht.

Mit diesem Ansatz erhalten Sie eine gute Vorstellung davon, ob Änderungen andere Teile des Systems betreffen, und können erforderliche Änderungen schneller vornehmen.

jamesj
quelle
3

Betreff: "Der ursprüngliche Code funktioniert möglicherweise nicht richtig":

Tests sind nicht in Stein gemeißelt. Sie können geändert werden. Und wenn Sie auf ein falsches Feature getestet haben, sollte es einfach sein, den Test korrekter umzuschreiben. Schließlich sollte sich nur das erwartete Ergebnis der getesteten Funktion geändert haben.

rem
quelle
1
IMO, einzelne Tests sollten in Stein gemeißelt sein, zumindest bis die Funktion, die sie testen, tot ist. Sie dienen dazu, das Verhalten des vorhandenen Systems zu überprüfen und den Betreuern zu versichern, dass ihre Änderungen keinen älteren Code beschädigen, der möglicherweise bereits auf diesem Verhalten beruht. Ändern Sie die Tests für eine Live-Funktion, und Sie entfernen diese Zusicherungen.
CHAO
3

Nun ja. Beantwortung als Software-Testingenieur. Zunächst sollten Sie alles testen, was Sie jemals getan haben. Denn wenn Sie dies nicht tun, wissen Sie nicht, ob es funktioniert oder nicht. Das mag uns offensichtlich erscheinen, aber ich habe Kollegen, die das anders sehen. Auch wenn es sich bei Ihrem Projekt um ein kleines Projekt handelt, das möglicherweise nie fertiggestellt wird, müssen Sie dem Benutzer ins Gesicht sehen und sagen, dass Sie wissen, dass es funktioniert, weil Sie es getestet haben.

Nicht-trivialer Code enthält immer Bugs (zitiert einen Typen von Uni; und wenn es keine Bugs gibt, ist es trivial) und unsere Aufgabe ist es, diese vor dem Kunden zu finden. Legacy-Code weist Legacy-Fehler auf. Wenn der ursprüngliche Code nicht so funktioniert, wie er sollte, glauben Sie mir. Bugs sind in Ordnung, wenn Sie sie kennen, haben Sie keine Angst, sie zu finden. Dafür sind Release Notes gedacht.

Wenn ich mich recht erinnere, heißt es im Refactoring-Buch, dass man sowieso ständig testen muss. Es ist also Teil des Prozesses.

RedSonja
quelle
3

Führen Sie die automatisierte Testabdeckung durch.

Passen Sie auf Wunschdenken auf, sowohl von Ihnen selbst als auch von Ihren Kunden und Vorgesetzten. So sehr ich auch gerne glauben möchte, dass meine Änderungen beim ersten Mal korrekt sind und ich sie nur einmal testen muss, so habe ich gelernt, diese Art des Denkens genauso zu behandeln wie nigerianische Betrugs-E-Mails. Meistens; Ich habe noch nie eine betrügerische E-Mail erhalten, habe aber kürzlich (als ich angeschrien habe) nachgegeben, dass ich keine Best Practices verwende. Es war eine schmerzhafte Erfahrung, die sich (teuer) hin und her zog. Nie wieder!

Ich habe ein Lieblingszitat aus dem Freefall-Webcomic: "Haben Sie jemals in einem komplexen Bereich gearbeitet, in dem der Supervisor nur eine ungefähre Vorstellung von den technischen Details hat? ... Dann wissen Sie, dass es der sicherste Weg ist, Ihren Supervisor zum Scheitern zu bringen befolgen Sie jede Bestellung ohne Frage. "

Es ist wahrscheinlich angebracht, die Zeit zu begrenzen, die Sie investieren.

Technophile
quelle
1

Wenn Sie mit einer großen Menge von Legacy-Code zu tun haben, der derzeit nicht getestet wird, ist es die richtige Entscheidung, jetzt eine Testabdeckung zu erhalten, anstatt in Zukunft auf eine hypothetische umfassende Neuschreibung zu warten. Mit dem Schreiben von Unit-Tests zu beginnen, ist nicht.

Ohne automatisierte Tests müssen Sie nach Änderungen am Code einige manuelle End-to-End-Tests der App durchführen, um sicherzustellen, dass sie funktioniert. Beginnen Sie damit, Integrationstests auf hoher Ebene zu schreiben, um diese zu ersetzen. Wenn Ihre App Dateien einliest, validiert, die Daten auf irgendeine Weise verarbeitet und die Ergebnisse anzeigt, die Sie mit Tests erfassen möchten.

Idealerweise verfügen Sie entweder über Daten aus einem manuellen Testplan oder können ein Beispiel der tatsächlichen Produktionsdaten zur Verwendung abrufen. Wenn nicht, da die App in der Produktion ist, macht sie in den meisten Fällen das, was sie sein sollte, also erstelle Daten, die alle Höhepunkte erreichen und nehme an, dass die Ausgabe vorerst korrekt ist. Es ist nicht schlimmer, als eine kleine Funktion zu übernehmen, vorausgesetzt, sie tut, wie es heißt, oder Kommentare legen nahe, dass dies der Fall ist, und Tests zu schreiben, vorausgesetzt, sie funktioniert ordnungsgemäß.

IntegrationTestCase1()
{
    var input = ReadDataFile("path\to\test\data\case1in.ext");
    bool validInput = ValidateData(input);
    Assert.IsTrue(validInput);

    var processedData = ProcessData(input);
    Assert.AreEqual(0, processedData.Errors.Count);

    bool writeError = WriteFile(processedData, "temp\file.ext");
    Assert.IsFalse(writeError);

    bool filesAreEqual = CompareFiles("temp\file.ext", "path\to\test\data\case1out.ext");
    Assert.IsTrue(filesAreEqual);
}

Wenn Sie genug von diesen Tests auf hoher Ebene haben, um den normalen Betrieb der Apps und die häufigsten Fehlerfälle zu erfassen, müssen Sie viel Zeit auf der Tastatur verbringen, um zu versuchen, Fehler aus dem Code herauszufinden, die etwas anderes tun als was Sie dachten, dass dies zu einem erheblichen Rückgang führen würde, was das zukünftige Refactoring (oder sogar ein umfangreiches Umschreiben) erheblich vereinfacht.

Wenn Sie die Abdeckung der Komponententests erweitern können, können Sie die meisten Integrationstests reduzieren oder sogar einstellen. Wenn Ihre App Dateien liest / schreibt oder auf eine Datenbank zugreift, ist es naheliegend, diese Teile einzeln zu testen und sie entweder zu verspotten oder die Datenstrukturen zu erstellen, die aus der Datei / Datenbank gelesen werden. Das eigentliche Erstellen dieser Testinfrastruktur dauert viel länger als das Schreiben einer Reihe schneller und unsauberer Tests. und jedes Mal, wenn Sie einen 2-minütigen Satz von Integrationstests ausführen, anstatt 30 Minuten manuell zu verbringen, um einen Bruchteil dessen zu testen, was die Integrationstests abgedeckt haben, erzielen Sie bereits einen großen Gewinn.

Dan Neely
quelle