Lohnt sich Unit Testing? [geschlossen]


572

Ich arbeite daran, Unit-Tests in den Entwicklungsprozess des Teams zu integrieren, in dem ich arbeite, und es gibt einige Skeptiker. Was sind einige gute Möglichkeiten, um die skeptischen Entwickler im Team vom Wert von Unit Testing zu überzeugen? In meinem speziellen Fall würden wir Unit-Tests hinzufügen, wenn wir Funktionen hinzufügen oder Fehler beheben. Leider eignet sich unsere Codebasis nicht für einfache Tests.


25
Wie kann man so etwas fragen .. Unit-Tests sind so hip :)? Im Ernst ... die allgemeine Idee ist dieselbe ... führen Sie Unit-Tests durch, wenn Sie der Meinung sind, dass die Vorteile die Kosten überwiegen ... wenn Sie Gründe haben, etwas anderes zu glauben ... finden Sie etwas anderes, das hilft.
Gishu

14
(regelmäßige Asserts mit Debug \ Release Build + saubere Schnittstelle zu Klassen + dedizierter Dummy-Tester)> Unit-Test
Viktor Sehr

110
Nachdem ich in einigen Teams mit der gleichen Einstellung war, habe ich die Erfahrung gemacht, dass Sie Ihre Zeit verschwenden. Die Skeptiker geben Ihnen nur den Überblick und werden Sie sabotieren und blockieren, bis Sie frustriert sind und zu einer Organisation wechseln, die Ihre Werte teilt. Welches ist wahrscheinlich, was Sie tun sollten. Wenn der "Anführer" des Teams einer der Skeptiker ist, denken Sie ernsthaft darüber nach, auszusteigen. Ich habe diese Art von Widerstand gegen Unit-Tests nur als die Spitze des Eisbergs schlechter Entwicklungspraktiken gesehen.
Rob

7
@ViktorSehr: Unit-Tests stehen nicht im Gegensatz zu sauberen Schnittstellen, sondern sind bei der Anwendung von TDD genau umgekehrt. Entweder das oder Fahrersitz + Lenkrad> Garage.
Jonas Byström

5
Unit-Tests sind eine massive Zeitverschwendung, die selten Fehler entdeckt, aber 30% der Zeit und des Budgets für Fehlerbehebung und Entwicklung verschlingt
Dominic

Antworten:


722

Jeden Tag gibt es in unserem Büro einen Austausch, der ungefähr so ​​abläuft:

"Mann, ich liebe Unit-Tests einfach, ich konnte nur eine Reihe von Änderungen an der Funktionsweise von etwas vornehmen und dann bestätigen, dass ich nichts kaputt gemacht habe, indem ich den Test erneut durchgeführt habe ..."

Die Details ändern sich täglich, das Gefühl jedoch nicht. Unit-Tests und testgetriebene Entwicklung (TDD) haben so viele versteckte und persönliche Vorteile wie die offensichtlichen, die man jemandem erst wirklich erklären kann, wenn er es selbst tut.

Aber wenn ich das ignoriere, hier ist mein Versuch!

  1. Mit Unit Tests können Sie schnell große Änderungen am Code vornehmen. Sie wissen, dass es jetzt funktioniert, weil Sie die Tests ausgeführt haben. Wenn Sie die Änderungen vornehmen, die Sie vornehmen müssen, müssen Sie die Tests wieder zum Laufen bringen. Das spart Stunden.

  2. Mit TDD können Sie erkennen, wann Sie mit dem Codieren aufhören müssen. Ihre Tests geben Ihnen die Gewissheit, dass Sie vorerst genug getan haben, und können aufhören zu optimieren und mit dem nächsten Schritt fortfahren.

  3. Die Tests und der Code arbeiten zusammen, um einen besseren Code zu erzielen. Ihr Code könnte schlecht / fehlerhaft sein. Ihr TEST könnte schlecht / fehlerhaft sein. In TDD setzen Sie auf die Wahrscheinlichkeit, dass beide schlecht / fehlerhaft sind. Oft muss der Test repariert werden, aber das ist immer noch ein gutes Ergebnis.

  4. TDD hilft bei der Kodierung von Verstopfung. Wenn Sie vor einer großen und entmutigenden Arbeit stehen, werden Sie mit den Tests schnell Fortschritte machen.

  5. Unit Tests helfen Ihnen dabei, das Design des Codes, an dem Sie arbeiten, wirklich zu verstehen. Anstatt Code zu schreiben, um etwas zu tun, skizzieren Sie zunächst alle Bedingungen, denen Sie den Code unterwerfen, und welche Ausgaben Sie davon erwarten würden.

  6. Unit Tests geben Ihnen sofort visuelles Feedback. Wir alle mögen das Gefühl all dieser grünen Lichter, wenn wir fertig sind. Es ist sehr befriedigend. Es ist auch viel einfacher zu erkennen, wo Sie nach einer Unterbrechung aufgehört haben, da Sie sehen können, wo Sie angekommen sind - das nächste rote Licht, das repariert werden muss.

  7. Entgegen der weit verbreiteten Meinung bedeutet Unit-Testing nicht, doppelt so viel Code zu schreiben oder langsamer zu codieren. Es ist schneller und robuster als das Codieren ohne Tests, sobald Sie den Dreh raus haben. Testcode selbst ist normalerweise relativ trivial und fügt dem, was Sie tun, keinen großen Aufwand hinzu. Dies ist eine, die du nur glauben wirst, wenn du es tust :)

  8. Ich denke, es war Fowler, der sagte: "Unvollkommene Tests, die häufig ausgeführt werden, sind viel besser als perfekte Tests, die überhaupt nicht geschrieben werden." Ich interpretiere dies so, dass ich die Erlaubnis habe, Tests zu schreiben, bei denen ich denke, dass sie am nützlichsten sind, selbst wenn der Rest meiner Codeabdeckung absolut unvollständig ist.

  9. Gute Unit-Tests können helfen, zu dokumentieren und zu definieren, was etwas tun soll

  10. Unit-Tests helfen bei der Wiederverwendung von Code. Migrieren Sie sowohl Ihren Code als auch Ihre Tests in Ihr neues Projekt. Passen Sie den Code an, bis die Tests erneut ausgeführt werden.

Eine Menge Arbeit, mit der ich zu tun habe, funktioniert nicht gut mit Unit-Tests (Benutzerinteraktionen mit Webanwendungen usw.), aber trotzdem sind wir alle in diesem Shop testinfiziert und am glücklichsten, wenn wir unsere Tests gebunden haben. Ich kann den Ansatz nicht genug empfehlen.


Ist die Präsentation, die Sie verknüpfen, eine .xul?
user2427

3
Die Frage betraf Unit-Tests. TDD ist eine ganz andere Sache als Unit-Tests.
ZunTzu

421

Unit-Tests ähneln dem Gehen ins Fitnessstudio. Sie wissen, dass es gut für Sie ist, alle Argumente sind sinnvoll, also fangen Sie an zu trainieren. Es gibt einen anfänglichen Ansturm, der großartig ist, aber nach ein paar Tagen fragt man sich, ob sich die Mühe lohnt. Sie nehmen sich eine Stunde Zeit, um sich umzuziehen und auf einem Hamsterrad zu laufen, und Sie sind sich nicht sicher, ob Sie wirklich etwas anderes als schmerzende Beine und Arme gewinnen.

Dann, nach vielleicht ein oder zwei Wochen, als die Schmerzen verschwinden, nähert sich eine große Frist. Sie müssen jede wache Stunde damit verbringen, "nützliche" Arbeit zu erledigen, damit Sie überflüssige Dinge wie das Gehen ins Fitnessstudio herausschneiden. Sie fallen aus der Gewohnheit heraus und wenn die große Frist abgelaufen ist, sind Sie wieder auf dem ersten Platz. Wenn Sie es überhaupt schaffen, wieder ins Fitnessstudio zu kommen, fühlen Sie sich genauso wund wie beim ersten Mal.

Sie lesen etwas, um zu sehen, ob Sie etwas falsch machen. Sie fühlen sich ein wenig irrational trotz all der gesunden, glücklichen Menschen, die die Tugenden der Bewegung preisen. Sie erkennen, dass Sie nicht viel gemeinsam haben. Sie müssen nicht 15 Minuten aus dem Weg fahren, um ins Fitnessstudio zu gehen. Es gibt einen in ihrem Gebäude. Sie müssen sich mit niemandem über die Vorteile von Bewegung streiten. es ist nur etwas, was jeder tut und als wichtig akzeptiert. Wenn sich eine große Frist nähert, wird ihnen nicht gesagt, dass Bewegung nicht mehr unnötig ist, als Ihr Chef Sie bitten würde, mit dem Essen aufzuhören.

Um Ihre Frage zu beantworten, lohnt sich Unit Testing normalerweise, aber der Aufwand ist nicht für alle gleich. Unit-Tests können einen enormen Aufwand erfordern, wenn Sie mit Spaghetti-Codebasis in einem Unternehmen arbeiten, das die Codequalität nicht wirklich schätzt. (Viele Manager werden das Lob von Unit Testing singen, aber das bedeutet nicht, dass sie sich dafür einsetzen werden, wenn es darauf ankommt.)

Wenn Sie versuchen, Unit Testing in Ihre Arbeit einzuführen und nicht all den Sonnenschein und Regenbogen sehen, den Sie erwartet haben, geben Sie sich keine Vorwürfe. Möglicherweise müssen Sie einen neuen Job finden, damit Unit Testing wirklich für Sie funktioniert.


15
tolle Anekdote!
Sander Versluys

68
Ihre Ideen faszinieren mich und ich möchte Ihren Newsletter abonnieren.
Christopher Parker

165
Mist, ich habe bereits Unit-Tests durchgeführt, aber jetzt habe ich das Gefühl, ich muss ins Fitnessstudio.
Vince

16
Ich mag es auch nicht. Ich versage als Geek und als Mensch.
Greg

13
+1: Viele Manager werden das Lob von Unit Testing singen, aber das bedeutet nicht, dass sie sich dafür einsetzen, wenn es darauf ankommt ... Möglicherweise müssen Sie einen neuen Job finden, damit Unit Testing wirklich für Sie funktioniert. - Großartige Punkte. Sehr richtig.
Jim G.

136

Der beste Weg, um zu überzeugen ... einen Fehler zu finden, einen Komponententest dafür zu schreiben, den Fehler zu beheben.

Es ist unwahrscheinlich, dass dieser bestimmte Fehler jemals wieder auftritt, und Sie können ihn mit Ihrem Test beweisen.

Wenn Sie dies genug tun, werden andere schnell verstehen.


56
Dies funktioniert nur, wenn Ihr Code so erstellt ist, dass Unit-Tests erleichtert werden (oder Sie TypeMock verwenden). Andernfalls werden Sie Äonen damit verbringen, den Test zu erstellen. Der meiste Code ohne Komponententests wird mit harten Abhängigkeiten (dh überall neuen) oder statischen Methoden erstellt. Dies macht es fast unmöglich, nur einen schnellen Unit-Test durchzuführen.
Andrew

7
@Rei - Der nachweisbare Fehlerbericht ist großartig, aber Sie werden den Fehler nur EINMAL reproduzieren. 2 Jahre später wird Ihr Komponententest den Code noch überprüfen, lange nachdem der Fehlerbericht geschlossen und vergessen wurde.
Orion Edwards

4
Es speichert den Fix Bug 1 ... Test ... gut. Benutzer finden Fehler 2 ... beheben ... testen ... gut. Benutzer finden Fehler 1 erneut. Aufschäumen, ausspülen, wiederholen. Dies geschieht, weil Sie einen Fehler behoben haben, den anderen verursachen und umgekehrt.
CaffGeek

1
@Rei Miyasaka: "Vielleicht, wenn Sie mehrere Leute haben, die das Projekt warten" - ich würde sagen, dass fast alle nicht trivialen Projekte dies tun. In Bezug auf „lassen Sie einfach einen Kommentar“: Das Problem ist , dass es (dh wird ) mit anderen Code - Interaktionen sein , die die Fehler wieder auftauchen verursachen könnten. Deshalb muss man eigentlich darauf testen.
Sleske

5
Beachten Sie jedoch, dass Tests zur Verhinderung von Regressionen in der Regel Integrationstests und keine Komponententests sind (da meiner Erfahrung nach die meisten Fehler nicht nur in einem Teil des Codes enthalten sind, sondern aus der Kombination mehrerer Codeteile resultieren, sodass Sie dies nur können reproduzieren Sie sie, indem Sie alle diese Stücke kombinieren).
Sleske

69

Die sprechende Walnuss fragt:

Was sind einige gute Möglichkeiten, um die skeptischen Entwickler im Team vom Wert von Unit Testing zu überzeugen?

Jeder hier wird aus heiterem Himmel viele Gründe anhäufen, warum Unit-Tests gut sind. Ich finde jedoch, dass der beste Weg, jemanden von etwas zu überzeugen, oft darin besteht, auf seine Argumentation zu hören und sie Punkt für Punkt anzusprechen. Wenn Sie zuhören und ihnen helfen, ihre Bedenken zu verbalisieren, können Sie jedes einzelne ansprechen und sie möglicherweise in Ihre Sichtweise umwandeln (oder sie zumindest ohne ein Bein stehen lassen, auf dem sie stehen können). Wer weiß? Vielleicht überzeugen sie Sie, warum Unit-Tests für Ihre Situation nicht geeignet sind. Nicht wahrscheinlich, aber möglich. Wenn Sie ihre Argumente gegen Unit-Tests veröffentlichen, können wir Ihnen möglicherweise dabei helfen, die Gegenargumente zu identifizieren.

Es ist wichtig, beide Seiten des Arguments anzuhören und zu verstehen. Wenn Sie versuchen, Unit-Tests ohne Rücksicht auf die Bedenken der Menschen zu eifrig durchzuführen, kommt es zu einem Religionskrieg (und wahrscheinlich zu wirklich wertlosen Unit-Tests). Wenn Sie es langsam anwenden und es zunächst dort anwenden, wo Sie den größten Nutzen bei geringsten Kosten sehen, können Sie möglicherweise den Wert von Komponententests demonstrieren und haben eine bessere Chance, Menschen zu überzeugen. Mir ist klar, dass dies nicht so einfach ist, wie es sich anhört - es erfordert normalerweise einige Zeit und sorgfältige Metriken, um ein überzeugendes Argument zu erstellen.

Unit-Tests sind wie jedes andere Tool und sollten so angewendet werden, dass die Vorteile (das Auffinden von Fehlern) die Kosten (den Aufwand beim Schreiben) überwiegen. Verwenden Sie sie nicht, wenn / wo sie keinen Sinn ergeben, und denken Sie daran, dass sie nur ein Teil Ihres Arsenals an Werkzeugen sind (z. B. Inspektionen, Behauptungen, Codeanalysatoren, formale Methoden usw.). Was ich meinen Entwicklern sage, ist Folgendes:

  1. Sie können das Schreiben eines Tests für eine Methode überspringen, wenn sie ein gutes Argument dafür haben, warum dies nicht erforderlich ist (z. B. zu einfach, um es wert zu sein, oder zu schwierig, um es wert zu sein) und wie die Methode anderweitig überprüft wird (z. B. Inspektion, Behauptungen , formale Methoden, interaktive / Integrationstests). Sie müssen berücksichtigen, dass einige Überprüfungen wie Inspektionen und formale Nachweise zu einem bestimmten Zeitpunkt durchgeführt werden und dann jedes Mal wiederholt werden müssen, wenn sich der Produktionscode ändert, während Komponententests und Zusicherungen als Regressionstests verwendet werden können (einmal geschrieben und danach wiederholt ausgeführt) ). Manchmal stimme ich ihnen zu, aber öfter werde ich darüber diskutieren, ob eine Methode wirklich zu einfach oder zu schwer zu testen ist.

    • Wenn ein Entwickler argumentiert, dass eine Methode zu einfach zu scheitern scheint, lohnt es sich dann nicht, sich die 60 Sekunden zu nehmen, um einen einfachen 5-Zeilen-Komponententest dafür zu erstellen? Diese 5 Codezeilen werden jede Nacht (Sie erstellen jede Nacht Builds, oder?) Für das nächste Jahr oder länger ausgeführt und sind die Mühe wert, wenn auch nur einmal ein Problem erkannt wird, dessen Identifizierung möglicherweise 15 Minuten oder länger gedauert hat und debuggen. Außerdem erhöht das Schreiben der einfachen Komponententests die Anzahl der Komponententests, wodurch der Entwickler gut aussieht.

    • Wenn ein Entwickler hingegen argumentiert, dass eine Methode zu schwierig zu testen scheint (was den erheblichen Aufwand nicht wert ist), ist dies möglicherweise ein guter Hinweis darauf, dass die Methode aufgeteilt oder überarbeitet werden muss, um die einfachen Teile zu testen. In der Regel sind dies Methoden, die auf ungewöhnlichen Ressourcen wie Singletons, der aktuellen Zeit oder externen Ressourcen wie einer Datenbank-Ergebnismenge beruhen. Diese Methoden müssen normalerweise in eine Methode umgestaltet werden, die die Ressource abruft (z. B. ruft getTime () auf), und in eine Methode, die die Ressource als Argument verwendet (z. B. den Zeitstempel als Parameter verwendet). Ich lasse sie das Testen der Methode überspringen, mit der die Ressource abgerufen wird, und sie schreiben stattdessen einen Komponententest für die Methode, die die Ressource jetzt als Argument verwendet. In der Regel ist das Schreiben des Unit-Tests dadurch viel einfacher und es lohnt sich daher, ihn zu schreiben.

  2. Der Entwickler muss eine "Linie in den Sand" ziehen, wie umfassend seine Unit-Tests sein sollten. Wenn wir später in der Entwicklung einen Fehler finden, sollten sie feststellen, ob umfassendere Komponententests das Problem erkannt hätten. Wenn dies der Fall ist und solche Fehler wiederholt auftreten, müssen sie die "Linie" verschieben, um in Zukunft umfassendere Komponententests zu schreiben (beginnend mit dem Hinzufügen oder Erweitern des Komponententests für den aktuellen Fehler). Sie müssen das richtige Gleichgewicht finden.

Es ist wichtig , die Unit - Tests zu realisieren sind kein Allheilmittel , und es ist so etwas wie zu viel Unit - Tests. Wenn wir an meinem Arbeitsplatz Lehren ziehen, höre ich unweigerlich "wir müssen mehr Komponententests schreiben". Das Management nickt zustimmend, weil ihnen "Unit Tests" == "gut" in den Kopf geschlagen wurde.

Wir müssen jedoch die Auswirkungen von "mehr Unit-Tests" verstehen. Ein Entwickler kann nur ~ N Codezeilen pro Woche schreiben, und Sie müssen herausfinden, wie viel Prozent dieses Codes Unit-Test-Code gegenüber Produktionscode sein sollten. Ein lockerer Arbeitsplatz verfügt möglicherweise über 10% des Codes als Komponententests und 90% des Codes als Produktionscode, was zu einem Produkt mit vielen (wenn auch sehr fehlerhaften) Funktionen führt (denken Sie an MS Word). Auf der anderen Seite wird ein strenger Laden mit 90% Unit-Tests und 10% Produktionscode ein absolut solides Produkt mit sehr wenigen Merkmalen haben (denken Sie an "vi"). Sie werden vielleicht nie Berichte über den Absturz des letzteren Produkts hören, aber das hat wahrscheinlich genauso viel damit zu tun, dass sich das Produkt nicht sehr gut verkauft, wie es mit der Qualität des Codes zu tun hat.

Schlimmer noch, vielleicht ist die einzige Gewissheit in der Softwareentwicklung, dass "Veränderungen unvermeidlich sind". Angenommen, der strenge Shop (90% Komponententests / 10% Produktionscode) erstellt ein Produkt mit genau 2 Merkmalen (unter der Annahme, dass 5% des Produktionscodes == 1 Merkmal sind). Wenn der Kunde vorbeikommt und eine der Funktionen ändert, werden durch diese Änderung 50% des Codes (45% der Komponententests und 5% des Produktionscodes) verworfen. Der laxe Laden (10% Unit-Tests / 90% Produktionscode) bietet ein Produkt mit 18 Funktionen, von denen keine sehr gut funktioniert. Ihr Kunde überarbeitet die Anforderungen für 4 seiner Funktionen vollständig. Obwohl die Änderung viermal so groß ist, wird nur die Hälfte der Codebasis verworfen (~ 25% = ~ 4,4% Komponententests + 20% des Produktionscodes).

Mein Punkt ist, dass Sie kommunizieren müssen, dass Sie das Gleichgewicht zwischen zu wenig und zu viel Unit-Test verstehen - im Wesentlichen, dass Sie beide Seiten des Problems durchdacht haben. Wenn Sie Ihre Kollegen und / oder Ihr Management davon überzeugen können, gewinnen Sie an Glaubwürdigkeit und haben möglicherweise eine bessere Chance, sie für sich zu gewinnen.


47
Wenn Vi nur sehr wenige Funktionen hat, verwenden Sie es nicht. ;)
Stefan Mai

1
+20 für Stefan, wenn ich könnte :)
Rob Grant

1
Testivus auf Test Coverage - googletesting.blogspot.com/2010/07/…
Bert F

Eine gute Analyse, obwohl ich zwei Dinge sagen würde. Sie scheinen davon auszugehen, dass zum Ändern einer Funktion der gesamte Code, auf den sie sich stützt, neu geschrieben werden muss, und es wird eher davon ausgegangen, dass eine lineare Beziehung zwischen Änderung und Änderung der Codemenge besteht. Außerdem hat ein Produkt mit geringen Tests mit größerer Wahrscheinlichkeit ein schlechteres Design, weshalb das Produkt mit vielen Funktionen mit ziemlicher Sicherheit pro Feature viel länger dauert (da es fast keine Tests und ein implizit schlechtes Design gibt).
nicodemus13

Das Schreiben eines Testfalls für einen einfachen Codeblock dient als Regressionsmechanismus - nur negativ, was ich gesehen habe, ist das Hinzufügen weiterer
Stapelrahmen

38

Ich habe mehrmals mit Unit-Tests gespielt und bin immer noch davon überzeugt, dass sich die Mühe angesichts meiner Situation lohnt.

Ich entwickle Websites, bei denen ein Großteil der Logik das Erstellen, Abrufen oder Aktualisieren von Daten in der Datenbank umfasst. Als ich versucht habe, die Datenbank zu Unit-Testzwecken zu "verspotten", ist sie sehr chaotisch geworden und schien ein bisschen sinnlos.

Wenn ich Unit-Tests rund um Geschäftslogik geschrieben habe, hat es mir auf lange Sicht nie wirklich geholfen. Da ich größtenteils nur an Projekten arbeite, neige ich dazu, intuitiv zu wissen, welche Codebereiche von etwas betroffen sein können, an dem ich arbeite, und ich teste diese Bereiche manuell. Ich möchte meinem Kunden so schnell wie möglich eine Lösung liefern, und Unit-Tests scheinen oft Zeitverschwendung zu sein. Ich liste manuelle Tests auf, gehe sie selbst durch und kreuze sie an, während ich gehe.

Ich kann sehen, dass es nützlich sein kann, wenn ein Entwicklerteam an einem Projekt arbeitet und den Code des anderen aktualisiert, aber selbst dann denke ich, dass gute Kommunikation und gut geschriebener Code oft ausreichen sollten, wenn die Entwickler von hoher Qualität sind .


8
Ich weiß, dass dies sehr alt ist, aber ich bin gezwungen zu kommentieren. Ich persönlich habe Erfolg beim Schreiben von Tests für meine Persistenzschicht gefunden. Starten Sie einfach eine Transaktion vor dem Test und rollen Sie sie anschließend zurück. Kein Spott nötig. Manchmal habe ich eine Klasse, um ein Datenarray abzurufen. Dann übergebe ich dieses Datenarray an eine zweite Klasse, die "Dinge" mit den Daten macht. Diese zweite Klasse berührt die Datenbank nicht. In diesem Fall gruppiere ich meine Tests. Diejenigen, die die erste Klasse testen und die Datenbank berühren, sind Funktionstests und werden selten ausgeführt. Die Tests für die letztere Klasse sind Komponententests und werden häufig ausgeführt.
Josh Ribakoff

4
Beim Testen dreht sich alles um Glück. Ich habe ein Paket mit 3900 Zeilen (PL / SQL), das automatisierte Buchungen im Hauptbuchsystem verarbeitet. Jetzt hasse ich es persönlich , mit Buchhaltern umzugehen - sie sind so wählerisch in Bezug auf kleine Dinge wie Bruchteile und so. Buncha anal-zurückhaltende arithmetische Geeks ... Ich weiß nicht. Mein Unit-Test-Paket für das Buchhaltungspaket umfasst ungefähr 22000 Zeilen und führt knapp 18000 Tests aus. Dies macht den Head Honcho in der Buchhaltung glücklich, und solange sich der Propeller auf seiner kleinen Mütze-Zählkappe glücklich dreht, bin ich glücklich ... :-)
Bob Jarvis - Reinstate Monica

31

Eine großartige Sache bei Unit-Tests ist, dass sie als Dokumentation für das Verhalten Ihres Codes dienen. Gute Tests sind wie eine Referenzimplementierung, und Teamkollegen können sie sich ansehen, um zu sehen, wie sie ihren Code in Ihren integrieren können.


26

Unit-Tests sind die anfängliche Investition wert. Seit ich vor ein paar Jahren angefangen habe, Unit-Tests zu verwenden, habe ich einige echte Vorteile gefunden:

  • Durch Regressionstests wird die Angst vor Änderungen am Code beseitigt (es gibt nichts Schöneres als das warme Leuchten, wenn Code bei jeder Änderung funktioniert oder explodiert).
  • ausführbare Codebeispiele für andere Teammitglieder (und Sie selbst in sechs Monaten ..)
  • gnadenloses Refactoring - das ist unglaublich lohnend, probieren Sie es aus!

Code-Schnipsel können eine große Hilfe sein, um den Aufwand für das Erstellen von Tests zu verringern. Es ist nicht schwierig, Snippets zu erstellen, mit denen in Sekundenschnelle eine Klassenübersicht und ein zugehöriges Unit-Test-Gerät erstellt werden können.


25

Sie sollten so wenig wie möglich testen!

Das heißt, Sie sollten gerade genug Unit-Tests schreiben, um die Absicht aufzudecken. Dies wird oft beschönigt. Unit-Tests kosten Sie. Wenn Sie Änderungen vornehmen und Tests ändern müssen, sind Sie weniger agil. Halten Sie Unit-Tests kurz und bündig. Dann haben sie viel Wert.

Zu oft sehe ich viele Tests, die niemals brechen werden, groß und ungeschickt sind und nicht viel Wert bieten. Sie verlangsamen dich nur.


23

Ich habe dies in keiner der anderen Antworten gesehen, aber eine Sache, die mir aufgefallen ist, ist, dass ich so viel schneller debuggen kann . Sie müssen Ihre App nicht mit der richtigen Abfolge von Schritten durchgehen, um zu dem Code zu gelangen, den Sie reparieren, sondern nur feststellen, dass Sie einen booleschen Fehler gemacht haben und alles erneut ausführen müssen. Mit einem Unit-Test können Sie direkt in den Code eintreten, den Sie debuggen.


21

[Ich muss darauf hinweisen, dass ich oben nichts sehen kann]

"Jeder Unit-Test, sie merken es nicht unbedingt - FAKT"

Denken Sie darüber nach, Sie schreiben eine Funktion, um möglicherweise eine Zeichenfolge zu analysieren und neue Zeilenzeichen zu entfernen. Als Neuling führen Sie entweder einige Fälle über die Befehlszeile durch, indem Sie es in Main () implementieren, oder Sie schlagen ein visuelles Frontend mit einer Schaltfläche zusammen, binden Ihre Funktion an ein paar Textfelder und eine Schaltfläche und sehen was geschieht.

Das ist Unit-Test - einfach und schlecht zusammengestellt, aber Sie testen den Code für einige Fälle.

Sie schreiben etwas komplexeres. Es wirft Fehler auf, wenn Sie einige Fälle durchwerfen (Unit-Tests) und den Code debuggen und verfolgen. Sie betrachten Werte beim Durchlaufen und entscheiden, ob sie richtig oder falsch sind. Dies ist bis zu einem gewissen Grad ein Unit-Test.

Unit-Tests hier nehmen dieses Verhalten wirklich auf, formalisieren es in ein strukturiertes Muster und speichern es, damit Sie diese Tests problemlos erneut ausführen können. Wenn Sie einen "richtigen" Unit-Testfall schreiben, anstatt ihn manuell zu testen, dauert es genauso lange oder weniger lange, als Sie erfahren haben, und Sie haben ihn zur Verfügung, um ihn immer wieder zu wiederholen


16

Ich habe jahrelang versucht, die Leute davon zu überzeugen, dass sie einen Unit-Test für ihren Code schreiben müssen. Unabhängig davon, ob sie die Tests zuerst geschrieben haben (wie in TDD) oder nachdem sie die Funktionalität codiert haben, habe ich immer versucht, ihnen alle Vorteile von Unit-Tests für Code zu erklären. Kaum jemand war mit mir nicht einverstanden. Sie können mit etwas nicht Offensichtlichem nicht einverstanden sein, und jede kluge Person wird die Vorteile von Unit-Test und TDD erkennen.

Das Problem beim Testen von Einheiten besteht darin, dass eine Verhaltensänderung erforderlich ist und es sehr schwierig ist, das Verhalten von Personen zu ändern. Mit Worten werden Sie eine Menge Leute dazu bringen, Ihnen zuzustimmen, aber Sie werden nicht viele Veränderungen in der Art und Weise sehen, wie sie Dinge tun.

Man muss die Leute davon überzeugen. Ihr persönlicher Erfolg wird mehr Menschen anziehen als alle Argumente, die Sie möglicherweise haben. Wenn sie sehen, dass Sie nicht nur über Unit Test oder TDD sprechen, sondern das tun, was Sie predigen, und Sie erfolgreich sind, werden die Leute versuchen, Sie nachzuahmen.

Sie sollten auch eine Hauptrolle übernehmen, da niemand beim ersten Mal einen Komponententest richtig schreibt. Daher müssen Sie ihn möglicherweise darin coachen, ihm den Weg und die ihm zur Verfügung stehenden Tools zeigen. Helfen Sie ihnen, während sie ihre ersten Tests schreiben, überprüfen Sie die Tests, die sie selbst schreiben, und zeigen Sie ihnen die Tricks, Redewendungen und Muster, die Sie durch Ihre eigenen Erfahrungen gelernt haben. Nach einer Weile werden sie die Vorteile selbst erkennen und ihr Verhalten ändern, um Unit-Tests oder TDD in ihre Toolbox aufzunehmen.

Änderungen werden nicht über Nacht stattfinden, aber mit ein wenig Geduld können Sie Ihr Ziel erreichen.


12

Ein wesentlicher Teil der testgetriebenen Entwicklung, der häufig beschönigt wird, ist das Schreiben von testbarem Code. Auf den ersten Blick scheint es eine Art Kompromiss zu sein, aber Sie werden feststellen, dass testbarer Code letztendlich auch modular, wartbar und lesbar ist. Wenn Sie weiterhin Hilfe benötigen, um Menschen zu überzeugen, ist dies eine schöne, einfache Präsentation über die Vorteile von Unit-Tests.


11

Wenn sich Ihre vorhandene Codebasis nicht für Unit-Tests eignet und bereits in Produktion ist, können Sie möglicherweise mehr Probleme verursachen als Sie lösen, indem Sie versuchen, Ihren gesamten Code so umzugestalten, dass er Unit-testbar ist.

Möglicherweise sollten Sie stattdessen Anstrengungen unternehmen, um Ihre Integrationstests zu verbessern. Es gibt viele Codes, die ohne Komponententest einfacher zu schreiben sind. Wenn eine Qualitätssicherung die Funktionalität anhand eines Anforderungsdokuments überprüfen kann, sind Sie fertig. Es versenden.

Das klassische Beispiel hierfür ist meiner Meinung nach ein SqlDataReader, der in eine ASPX-Seite eingebettet ist, die mit einer GridView verknüpft ist. Der Code befindet sich alle in der ASPX-Datei. Die SQL befindet sich in einer gespeicherten Prozedur. Was machst du Unit Test? Wenn die Seite das tut, was sie tun soll, sollten Sie sie dann wirklich in mehrere Ebenen umgestalten, damit Sie etwas automatisieren müssen?


10

Eines der besten Dinge beim Testen von Einheiten ist, dass Ihr Code dabei einfacher zu testen ist. Bereits vorhandener Code, der ohne Tests erstellt wurde, ist immer eine Herausforderung, da es nicht selten zu einem Kopplungsgrad zwischen Klassen und schwer zu konfigurierenden Objekten in Ihrer Klasse kommt - wie bei einer E-Mail Servicereferenz senden - und so weiter. Aber lass dich nicht stürzen! Sie werden feststellen, dass Ihr gesamtes Code-Design besser wird, wenn Sie mit dem Schreiben von Unit-Tests beginnen. Je mehr Sie testen, desto sicherer werden Sie, noch mehr Änderungen daran vorzunehmen, ohne befürchten zu müssen, dass Ihre Anwendung beschädigt wird oder Fehler auftreten .

Es gibt mehrere Gründe, Ihren Code einem Unit-Test zu unterziehen. Mit der Zeit werden Sie jedoch feststellen, dass die Zeit, die Sie beim Testen sparen, einer der besten Gründe dafür ist. In einem System, das ich gerade geliefert habe, bestand ich darauf, automatisierte Unit-Tests durchzuführen, obwohl behauptet wurde, ich würde viel mehr Zeit mit den Tests verbringen als mit dem manuellen Testen des Systems. Nachdem alle meine Unit-Tests durchgeführt wurden, führte ich mehr als 400 Testfälle in weniger als 10 Minuten aus. Jedes Mal, wenn ich eine kleine Änderung am Code vornehmen musste, musste ich nur zehn sicherstellen, dass der Code immer noch ohne Fehler funktionierte Protokoll. Können Sie sich vorstellen, wie viel Zeit man damit verbringen würde, diese über 400 Testfälle von Hand auszuführen?

Wenn es um automatisierte Tests geht - sei es Unit-Tests oder Abnahmetests -, ist es für jeden eine vergebliche Anstrengung, zu codieren, was Sie manuell tun können, und manchmal ist es wahr - wenn Sie vorhaben, Ihre Tests nur einmal auszuführen. Der beste Teil des automatisierten Testens besteht darin, dass Sie sie ohne Aufwand mehrmals ausführen können. Nach dem zweiten oder dritten Lauf ist die Zeit und der Aufwand, die Sie verschwendet haben, bereits bezahlt.

Ein letzter Ratschlag wäre, nicht nur Ihren Code zu testen, sondern zuerst mit dem Test zu beginnen (weitere Informationen finden Sie unter TDD und BDD ).


8

Unit-Tests sind auch besonders nützlich, wenn es darum geht, einen Code neu zu gestalten oder neu zu schreiben. Wenn Sie eine gute Abdeckung für Komponententests haben, können Sie diese mit Sicherheit umgestalten. Ohne Unit-Tests ist es oft schwierig sicherzustellen, dass Sie nichts kaputt gemacht haben.


7

Kurz gesagt - ja. Sie sind jede Unze Mühe wert ... bis zu einem gewissen Punkt. Tests sind letztendlich immer noch Code, und ähnlich wie beim typischen Code-Wachstum müssen Ihre Tests möglicherweise überarbeitet werden, um wartbar und nachhaltig zu sein. Es gibt eine Tonne GOTCHAS! Wenn es um Unit-Tests geht, aber Mann, Mann, Mann, nichts, und ich meine, NICHTS befähigt einen Entwickler, Änderungen sicherer vorzunehmen als eine Vielzahl von Unit-Tests.

Ich arbeite gerade an einem Projekt ... es ist etwas TDD, und wir haben den Großteil unserer Geschäftsregeln als Tests zusammengefasst ... wir haben derzeit ungefähr 500 Komponententests. In der vergangenen Iteration musste ich unsere Datenquelle und die Schnittstelle unserer Desktop-Anwendung zu dieser Datenquelle überarbeiten. Ich habe ein paar Tage gebraucht, die ganze Zeit habe ich nur Unit-Tests durchgeführt, um zu sehen, was ich kaputt gemacht und repariert habe. Nehmen Sie eine Änderung vor; Erstellen Sie Ihre Tests und führen Sie sie aus. Repariere, was du kaputt gemacht hast. Waschen, spülen, nach Bedarf wiederholen. Was traditionell Tage der Qualitätssicherung und des Bootsstresses gekostet hätte, war stattdessen eine kurze und erfreuliche Erfahrung.

Bereiten Sie sich im Voraus vor, ein wenig mehr Aufwand, und es zahlt sich später zehnmal aus, wenn Sie anfangen müssen, sich mit den Kernmerkmalen / -funktionen zu beschäftigen.

Ich habe dieses Buch gekauft - es ist eine Bibel mit xUnit-Testkenntnissen - es ist wahrscheinlich eines der Bücher, auf die in meinem Regal am häufigsten verwiesen wird, und ich konsultiere es täglich: Linktext


+1: aber Mann, Mann, Mann, nichts, und ich meine, NICHTS befähigt einen Entwickler, Änderungen sicherer vorzunehmen als eine Reihe von Unit-Tests. - So wahr. Ich wünschte, ich hätte das früher herausgefunden.
Jim G.

7

Gelegentlich verbringen entweder ich selbst oder einer meiner Mitarbeiter ein paar Stunden damit, einem leicht undurchsichtigen Fehler auf den Grund zu gehen, und sobald die Ursache des Fehlers gefunden ist, wird der Code in 90% der Fälle nicht auf Einheit getestet. Der Unit-Test existiert nicht, weil der Entwickler aus Zeitgründen Abstriche macht, aber dann dieses und mehr Debugging verliert.

Wenn Sie sich nur wenig Zeit nehmen, um einen Komponententest zu schreiben, können Sie Stunden beim zukünftigen Debuggen sparen.


+1: Wenn Sie sich nur wenig Zeit nehmen, um einen Komponententest zu schreiben, können Sie Stunden beim zukünftigen Debuggen sparen. - Jep!
Jim G.

7

Ich arbeite als Wartungstechniker mit einer schlecht dokumentierten, schrecklichen und großen Codebasis. Ich wünschte, die Leute, die den Code geschrieben haben, hätten die Unit-Tests dafür geschrieben.
Jedes Mal, wenn ich eine Änderung vornehme und den Produktionscode aktualisiere, habe ich Angst, dass ich einen Fehler einführen könnte, weil ich eine Bedingung nicht berücksichtigt habe.
Wenn sie den Test schreiben würden, wären Änderungen an der Codebasis einfacher und schneller (gleichzeitig wäre die Codebasis in einem besseren Zustand).

Ich denke, Unit-Tests erweisen sich als sehr nützlich, wenn Sie APIs oder Frameworks schreiben, die viele Jahre halten und von anderen Personen als den ursprünglichen Codierern verwendet / modifiziert / weiterentwickelt werden müssen.


Fügen Sie Komponententests für neuen Code oder Korrekturen hinzu, die Sie vornehmen?
o

6

Unit Testing ist definitiv die Mühe wert. Leider haben Sie ein schwieriges (aber leider häufiges) Szenario ausgewählt, in das Sie es implementieren möchten.

Der beste Vorteil von Unit-Tests besteht darin, dass Sie sie von Grund auf verwenden. Bei einigen ausgewählten, kleinen Projekten hatte ich das Glück, meine Unit-Tests vor der Implementierung meiner Klassen zu schreiben (die Benutzeroberfläche war bereits vollständig Punkt). Mit geeigneten Unit-Tests finden und beheben Sie Fehler in Ihren Klassen, während sie noch in den Kinderschuhen stecken, und nicht in der Nähe des komplexen Systems, in das sie zweifellos in Zukunft integriert werden.

Wenn Ihre Software solide objektorientiert ist, sollten Sie in der Lage sein, Unit-Tests auf Klassenebene ohne großen Aufwand hinzuzufügen. Wenn Sie nicht so viel Glück haben, sollten Sie trotzdem versuchen, Unit-Tests zu integrieren, wo immer Sie können. Stellen Sie sicher, dass beim Hinzufügen neuer Funktionen die neuen Teile mit klaren Schnittstellen gut definiert sind und dass Unit-Tests Ihr Leben erheblich erleichtern.


6

Wenn Sie sagten, "unsere Codebasis eignet sich nicht für einfache Tests", ist dies das erste Anzeichen für einen Codegeruch. Unit-Tests schreiben bedeutet, dass Sie Code normalerweise anders schreiben, um den Code testbarer zu machen. Dies ist meiner Meinung nach eine gute Sache, da ich im Laufe der Jahre beim Schreiben von Code, für den ich Tests schreiben musste, ein besseres Design entwickeln musste.


6

Ich weiß nicht. Viele Orte führen keine Unit-Tests durch, aber die Qualität des Codes ist gut. Microsoft führt Unit-Tests durch, aber Bill Gates gab bei seiner Präsentation einen Bluescreen.


Beachten Sie, dass dies vor fast 15 Jahren war, als Unit-Tests nicht so beliebt waren wie heute.
Fwielstra

1
Und Internet Explorer kann immer noch nicht viele Webseiten speichern.
Cees Timmerman

5

Ich habe einen sehr großen Blog-Beitrag über das Thema geschrieben. Ich habe festgestellt, dass Unit-Tests allein die Arbeit nicht wert sind und normalerweise gekürzt werden, wenn die Fristen näher rückt.

Anstatt über Unit-Tests unter dem Gesichtspunkt der "Test-After" -Verifizierung zu sprechen, sollten wir uns den wahren Wert ansehen, der gefunden wurde, als Sie vor der Implementierung eine Spezifikation / einen Test / eine Idee schreiben wollten.

Diese einfache Idee hat die Art und Weise, wie ich Software schreibe, verändert und ich würde nicht zum "alten" Weg zurückkehren.

Wie die erste Testentwicklung mein Leben verändert hat


1
+1 - und ich muss sagen, es ist umwerfend, wie viele Trolle dieser Blogeintrag angezogen hat (bevor Sie hier posten, wenn ich mich nicht irre).
Jeff Sternal

haha stimmte zu :) </ reddit Titelseite tut, wie es scheint>
Toran Billups

3

Ja - Unit Testing ist definitiv die Mühe wert, aber Sie sollten wissen, dass es keine Silberkugel ist. Unit Testing ist Arbeit und Sie müssen daran arbeiten, den Test auf dem neuesten Stand und relevant zu halten, wenn sich der Code ändert. Der angebotene Wert ist jedoch die Mühe wert, die Sie investieren müssen. Die Möglichkeit, ungestraft umzugestalten, ist ein großer Vorteil, da Sie die Funktionalität jederzeit validieren können indem Sie Ihre Tests nach einem Änderungscode ausführen. Der Trick besteht darin, sich nicht zu sehr auf die Arbeitseinheit einzulassen, die Sie testen, oder darauf, wie Sie die Anforderungen an Gerüsttests erfüllen und wann ein Komponententest wirklich ein Funktionstest usw. ist. Die Leute werden stundenlang über dieses Zeug streiten Am Ende ist die Realität, dass alle Tests, die Sie als Schreibcode durchführen, besser sind, als sie nicht durchzuführen. Das andere Axiom handelt von Qualität und nicht von Quantität - ich habe Codebasen mit 1000 'gesehen. s von Tests, die im Wesentlichen bedeutungslos sind, da der Rest nichts Nützliches oder Domänenspezifisches wie Geschäftsregeln usw. der jeweiligen Domäne wirklich testet. Ich habe auch Codebasen mit 30% Codeabdeckung gesehen, aber die Tests waren relevant, aussagekräftig und wirklich beeindruckend, da sie die Kernfunktionalität des Codes testeten, für den er geschrieben wurde, und ausdrückten, wie der Code verwendet werden sollte.

Einer meiner Lieblingstricks beim Erkunden neuer Frameworks oder Codebasen ist das Schreiben von Unit-Tests für 'it', um herauszufinden, wie die Dinge funktionieren. Es ist eine großartige Möglichkeit, mehr über etwas Neues zu erfahren, anstatt ein trockenes Dokument zu lesen :)


3

Ich habe kürzlich genau die gleiche Erfahrung an meinem Arbeitsplatz gemacht und festgestellt, dass die meisten von ihnen die theoretischen Vorteile kannten, aber über die Vorteile speziell für sie verkauft werden mussten. Daher hier die Punkte, die ich (erfolgreich) verwendet habe:

  • Sie sparen Zeit, wenn Sie negative Tests durchführen, bei denen Sie unerwartete Eingaben (Nullzeiger, Werte außerhalb der Grenzen usw.) verarbeiten, da Sie all dies in einem einzigen Prozess ausführen können.
  • Sie geben beim Kompilieren sofortiges Feedback zum Standard der Änderungen.
  • Sie sind nützlich, um interne Datendarstellungen zu testen, die während der normalen Laufzeit möglicherweise nicht verfügbar gemacht werden.

und der große ...

  • Möglicherweise müssen Sie keine Unit-Tests durchführen, aber wenn jemand anderes hereinkommt und den Code ohne umfassendes Verständnis ändert, kann er viele der dummen Fehler auffangen, die er möglicherweise macht.

+1: • Möglicherweise müssen Sie keine Komponententests durchführen, aber wenn jemand anderes hereinkommt und den Code ohne umfassendes Verständnis ändert, kann er viele der dummen Fehler auffangen, die er möglicherweise macht. - Jep. Angesichts des Umsatzes in der Softwareindustrie ist dies ein enormer Vorteil.
Jim G.

3

Ich habe TDD vor ein paar Jahren entdeckt und seitdem alle meine Lieblingsprojekte damit geschrieben. Ich habe geschätzt, dass es ungefähr genauso lange dauert, ein Projekt zu TDD zu machen wie einen Cowboy zusammen, aber ich habe so viel Vertrauen in das Endprodukt, dass ich das Gefühl habe, etwas erreicht zu haben.

Ich habe auch das Gefühl, dass es meinen Designstil verbessert (viel mehr schnittstellenorientiert, falls ich Dinge zusammen verspotten muss) und, wie der grüne Beitrag oben schreibt, bei "Codierungsverstopfung" hilft: wenn Sie nicht wissen, was Um als nächstes zu schreiben, oder wenn Sie eine entmutigende Aufgabe vor sich haben, können Sie klein schreiben.

Schließlich finde ich, dass die mit Abstand nützlichste Anwendung von TDD das Debuggen ist, schon allein deshalb, weil Sie bereits ein Abfrage-Framework entwickelt haben, mit dem Sie das Projekt dazu bringen können, den Fehler auf wiederholbare Weise zu erzeugen.


3

Eine Sache, die noch niemand erwähnt hat, ist die Verpflichtung aller Entwickler, vorhandene automatisierte Tests tatsächlich auszuführen und zu aktualisieren. Automatisierte Tests, zu denen Sie zurückkehren und die aufgrund neuer Entwicklungen als fehlerhaft eingestuft werden, verlieren viel an Wert und machen automatisierte Tests wirklich schmerzhaft. Die meisten dieser Tests weisen nicht auf Fehler hin, da der Entwickler den Code manuell getestet hat. Die Zeit, die für die Aktualisierung aufgewendet wird, ist also nur Verschwendung.

Die Skeptiker davon zu überzeugen, die Arbeit der anderen an Unit-Tests nicht zu zerstören, ist viel wichtiger, um Wert aus den Tests zu ziehen, und könnte einfacher sein.

Es ist weder produktiv noch macht Spaß, Stunden damit zu verbringen, Tests zu aktualisieren, die aufgrund neuer Funktionen bei jedem Update aus dem Repository unterbrochen wurden.


2

Wenn Sie NUnit verwenden, besteht eine einfache, aber effektive Demo darin, NUnits eigene Testsuite (n) vor ihnen auszuführen. Eine echte Testsuite zu sehen, die einer Codebasis ein Training gibt, sagt mehr als tausend Worte ...


2

Unit-Tests helfen sehr bei Projekten, die größer sind, als jeder Entwickler im Kopf behalten kann. Mit ihnen können Sie die Unit-Test-Suite vor dem Einchecken ausführen und feststellen, ob Sie etwas kaputt gemacht haben. Dies spart viel Zeit, wenn Sie sitzen und mit den Daumen drehen müssen, während Sie darauf warten, dass jemand anderes einen Fehler behebt, den er eingecheckt hat, oder wenn Sie sich die Mühe machen, das Wechselgeld zurückzusetzen, damit Sie etwas Arbeit erledigen können. Es ist auch beim Refactoring von unschätzbarem Wert, sodass Sie sicher sein können, dass der überarbeitete Code alle Tests besteht, die der ursprüngliche Code durchgeführt hat.


2

Mit der Unit Test Suite können Sie Änderungen am Code vornehmen, während die restlichen Funktionen erhalten bleiben. Es ist ein großer Vorteil. Verwenden Sie Unit Test Sutie und Regressionstestsuite, wenn Sie die Codierung neuer Funktionen abgeschlossen haben?


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.