- Ich spreche von Unit-Tests im TDD-Sinne. (Nicht automatisierte "Integration" oder wie Sie es nennen möchten Tests.)
- Legacy-Code wie in: (C ++) Code ohne Tests. (siehe: Michael Feathers ' Effektiv mit Legacy-Code arbeiten )
- Aber auch Legacy-Code wie in: Code, mit dem unser Team in den letzten 10-5 Jahren gearbeitet hat, sodass wir sehr oft eine gute Vorstellung davon haben, wo Dinge platziert werden müssen, um etwas zu ändern.
- Wir haben Unit-Tests für einige Module eingerichtet (über Boost.Test) , die später erschienen sind oder sich als " normal " für Unit-Tests erwiesen haben (allgemeine app-spezifische Container, Zeichenfolgen, Netzwerkhelfer usw.).
- Wir haben noch keine ordnungsgemäßen automatischen Abnahmetests.
Jetzt, vor kurzem, hatte ich das "Vergnügen", 3 neue benutzerbezogene Funktionen zu implementieren.
Ich brauchte jeweils 1-2 Stunden, um mich mit den zu ändernden Codeteilen vertraut zu machen, 1-2 Stunden, um den (kleinen) Code zu implementieren, den ich ändern musste, und weitere 1-2 Stunden, um sicherzustellen, dass die App funktioniert lief danach richtig und tat was es tun sollte.
Jetzt habe ich wirklich wenig Code hinzugefügt. (Ich denke, eine Methode und ein paar Anrufzeilen für jede Funktion.)
Factoring diesen Code aus (über eine der vorgeschlagenen Methoden in WEwLC ), so dass ein Unit - Test sinnvoll haben würde (und nicht um eine vollständige Tautologie gewesen) wäre leicht weiteren 2-4 Stunden in Anspruch genommen, wenn nicht mehr. Dies hätte zu jeder Funktion 50% -100% mehr Zeit ohne unmittelbaren Nutzen beigetragen
- Ich brauchte den Unit-Test nicht, um etwas über den Code zu verstehen
- Manuelles Testen ist derselbe Arbeitsaufwand, da ich noch testen muss, ob der Code richtig in den Rest der App integriert ist.
Zugegeben, wenn später "jemand" kam und diesen Code berührte, könnte er theoretisch einen gewissen Nutzen aus diesem Komponententest ziehen. (Nur theoretisch, da diese getestete Codeinsel in einem Ozean von ungetestetem Code leben würde.)
"Dieses Mal" habe ich mich also entschieden, die harte Arbeit des Hinzufügens eines Komponententests nicht zu übernehmen: Die Codeänderungen, um das zu testende Material zu erhalten, wären erheblich komplexer gewesen als die Codeänderungen, um die Funktion korrekt (und sauber) zu implementieren.
Ist dies typisch für stark gekoppelten Legacy-Code? Bin ich faul / setzen wir als Team die falschen Prioritäten? Oder bin ich umsichtig und teste nur Dinge, bei denen der Overhead nicht zu hoch ist?
quelle
Antworten:
In diesen Situationen muss man pragmatisch sein. Alles muss einen geschäftlichen Wert haben, aber das Unternehmen muss darauf vertrauen, dass Sie beurteilen, welchen Wert technische Arbeit hat. Ja, Unit-Tests haben immer einen Vorteil, aber ist dieser Vorteil groß genug, um die aufgewendete Zeit zu rechtfertigen?
Ich würde immer über neuen Code streiten, aber bei Legacy-Code muss man ein Urteil fällen.
Bist du oft in diesem Bereich des Codes? Dann gibt es Gründe für eine kontinuierliche Verbesserung. Nehmen Sie eine wesentliche Änderung vor? Dann gibt es einen Fall, dass es sich bereits um neuen Code handelt. Aber wenn Sie einen einzeiligen Code in einem komplexen Bereich erstellen, der wahrscheinlich ein Jahr lang nicht mehr angesprochen wird, sind die Kosten (ganz zu schweigen vom Risiko) für die Neuentwicklung natürlich zu hoch. Geben Sie einfach eine Codezeile ein und gehen Sie schnell duschen.
Faustregel: Denken Sie immer an sich selbst: " Glaube ich, dass das Unternehmen mehr von dieser technischen Arbeit profitiert, von der ich denke, dass ich sie tun sollte, als von der Arbeit, nach der sie gefragt haben, die sich infolgedessen verzögert? "
quelle
Der Vorteil von Unit-Tests im Sinne von TDD besteht darin, etwas zu erhalten, das für sich steht, ohne dass eine über Jahre hinweg von einem stabilen Team aufgebaute mündliche Überlieferung erforderlich ist.
Es ist ein großes Glück, dass dasselbe Team schon so lange an einem Projekt beteiligt ist. Aber das wird sich irgendwann ändern. Menschen werden krank, gelangweilt oder befördert. Sie ziehen um, ziehen sich zurück oder sterben. Neue kommen mit neuen Ideen und dem Drang, alles so umzugestalten, wie sie es in der Schule gelernt haben. Unternehmen werden verkauft und gekauft. Verwaltungsrichtlinien ändern sich.
Wenn Sie möchten, dass Ihr Projekt überlebt, müssen Sie es auf Änderungen vorbereiten.
quelle
Das Schreiben von Komponententests ist eine Zukunftssicherung Ihres Codes. Wenn die Codebasis keine Tests enthält, sollten Sie neue Tests für alle neuen Funktionen hinzufügen, da dies den Code nur ein wenig robuster macht.
Ich finde, dass das Hinzufügen von Tests, selbst in Legacy-Code, mittel- bis langfristig vorteilhaft ist. Wenn es Ihrem Unternehmen mittel- bis langfristig egal ist, würde ich ein anderes Unternehmen suchen. Außerdem glaube ich nicht, dass das manuelle Testen länger dauert als das Schreiben eines festgelegten Komponententests. In diesem Fall müssen Sie Code-Kata üben, die sich auf das Schreiben von Tests konzentriert.
quelle
Best Practices schreiben vor, dass Sie jeden Code, den Sie ändern, einem Komponententest unterziehen sollten. Die Codierung in der realen Welt ist jedoch mit vielen Kompromissen verbunden, da Zeit und Material begrenzt sind.
Sie müssen lediglich die tatsächlichen Kosten für das Beheben von Fehlern und das Vornehmen von Änderungen ohne Komponententests bewerten. Sie können dann die Investition in die Erstellung dieser Tests bewerten. Unit-Tests reduzieren die Kosten für zukünftige Arbeiten erheblich, haben aber jetzt ihren Preis.
Unterm Strich lohnt es sich möglicherweise nicht, Unit-Tests zu schreiben, wenn Ihr System selten geändert wird. Wenn es jedoch regelmäßigen Änderungen unterliegt, lohnt es sich.
quelle
All diese kleinen rationalen Entscheidungen, keine Tests zu erstellen, führen zu einer lähmenden technischen Verschuldung, die Sie verfolgen wird, wenn jemand abreist und ein neuer Mitarbeiter eingestellt werden muss.
Ja, das Schreiben der Einheitentests hat möglicherweise weitere 2-3 Stunden gekostet. Wenn der Code jedoch vom Testen zurückgesendet wird, müssen Sie alles manuell erneut testen und Ihre Tests erneut dokumentieren - tun Sie das, nicht wahr? Woher weiß sonst jemand, was Sie getestet haben und welche Werte Sie verwendet haben?
Unit-Tests dokumentieren das erwartete Verhalten des Codes, die Testdaten, die zur Überprüfung der Funktionalität verwendet wurden, und geben neuen Codierern die Gewissheit, dass sie beim Vornehmen von Änderungen nichts kaputt gemacht haben.
Es kostet heute ein paar Stunden mehr als manuelles Testen, aber Sie testen jedes Mal, wenn Sie Änderungen vornehmen, um Stunden über die Lebensdauer des Codes zu sparen.
Wenn Sie jedoch wissen, dass der Code in ein paar Jahren in den Ruhestand geht, haben sich alle von mir genannten Änderungen geändert, da Sie die Tests im Code nicht abgeschlossen haben und es sich nie auszahlt.
quelle
Der Wert von Komponententests besteht nicht nur darin, ein neues Feature zu testen, wenn es entwickelt wird. Der Nutzen von Unit-Tests wird größtenteils in der Zukunft erzielt.
Ja, Sie müssen möglicherweise ausgeben , was scheint wie eine ungeregelte Menge Zeit , um Ihren Legacy - Code testbar zu machen.
Wenn Sie dies nicht tun, werden oder sollten Sie noch viele, viele, viele Stunden damit verbringen, die Funktion zu testen. Nicht nur bei der ersten Entwicklung, sondern bei jeder neuen Version Ihrer Software. Ohne Sie und andere Formen des automatisierten Testens haben Sie keine andere Möglichkeit, als viele Stunden manuell zu testen, um sicherzustellen, dass Ihre Funktion nicht versehentlich beschädigt wurde, selbst wenn diese Funktion selbst nicht geändert wurde.
quelle