Wie haben Sie Unit-Tests angenehmer gemacht? [geschlossen]

18

Wenn Sie Unit-Tests schon immer geliebt haben, ist das gut für Sie! Aber für die Unglücklichen, die nicht mit Vorliebe geboren wurden, wie haben Sie es geschafft, diese Aufgabe angenehmer zu gestalten?

Dies ist keine Frage "Was ist der richtige Weg zum Komponententest?". Ich möchte einfach nur kleine persönliche Tricks kennen lernen, die die Langeweile beim Schreiben von Unit-Tests verringern.

Preets
quelle
1
Ich liebe es, Komponententests und andere Tests zu schreiben, zum Teil, weil fast alle anderen daran scheißen (manchmal saugen sie auch daran, Werkzeuge herzustellen, die ich teste). Nein, ich sauge nicht als Entwickler. Ich mag einfach Usability, Eye Candy und Automation. Die MbUnitBibliothek hat mein Leben verändert. Autotests sind wichtig. Automatisches Testen spart Zeit. Automatisches Testen spart Geld. Selbsttests können Leben retten. Autotests sind der einzige Weg. Autotests sind ein weiteres Sicherheitsnetz. Wenn ich einer von 50 Menschen bin, die an einer riesigen Architektur arbeiten, fühle ich mich wie ein weiterer Stein in einer Mauer. Mit Unit-Tests habe ich die Kontrolle.
Job
Faulheit und Frustration beim Testen von Einheiten ist eine normale Reaktion auf die Arbeit, die unser Gehirn als nutzlos empfindet. Ich hasse es, Komponententests zu schreiben und zu pflegen, die einen geringen oder negativen ROI aufweisen. Nützliche Tests zu schreiben ist eine angenehme Aufgabe, aber es ist eine Fähigkeit für sich, zu erkennen, was nützlich und was Müll ist. Es gibt einen Mann, der ein Buch zu diesem Thema auf der Grundlage seines Blogs schreibt. Sie können es hier lesen: enterprisecraftsmanship.com/2016/06/01/…
KolA

Antworten:

22

Erstens stimme ich Ihnen zu - wenn Sie Ihre Komponententests mit bereits fertiggestelltem Code schreiben oder Ihren Code manuell testen, finde ich das auch äußerst langweilig.

Ich finde, dass es für mich zwei Möglichkeiten zum Testen von Einheiten gibt, die es wirklich angenehm machen:

  1. Durch die Verwendung von Test Driven Development (TDD) - wenn ich die Tests zuerst schreibe, kann ich über die nächste Funktionalität oder das nächste Verhalten nachdenken, die bzw. das ich in meinem Code benötige. Ich finde es äußerst lohnend und unterhaltsam, in winzigen Schritten meinem Endziel näher zu kommen und alle paar Minuten spürbare Fortschritte zu erzielen.
  2. Wenn es Fehler gibt, ist es eine unterhaltsame Herausforderung, einen fehlgeschlagenen Komponententest zu schreiben, der den Fehler reproduziert, anstatt direkt zum Debugger zu gehen. Es ist äußerst befriedigend, endlich die Umstände herauszufinden, die einen Fehler in Ihrem Code verursachen, ihn dann zu beheben und zu beobachten, wie der Balken für den neuen Fehlertest grün wird (und für alle vorhandenen Tests grün bleibt).
Paddyslacker
quelle
12

Selbstgefällige Überlegenheit.

Ich mache nur einen Scherz. "Sieh mich an und kultiviere gute Programmiergewohnheiten! Dieses 'Unit-Testing'-Zeug ist etwas, was ich vor zehn Jahren noch nie gemacht hätte - was für ein Idiot! Und denke nur an all die Fehler, die ich als Folge davon bekommen werde Diese langweilige, mühsame Arbeit, die ich gerade mache - mein Code wird fantastisch sein! Ich werde mit Sicherheit eine Gehaltserhöhung erhalten! * "

* - Nein, werde ich nicht.

Ich finde, es ist wie trainieren oder gesund essen; Bis die greifbaren Vorteile tatsächlich greifen ("Heilige Bälle, ich fange wirklich eine Menge von Regressionsfehlern, die sich in die Produktion eingeschlichen hätten!"), kann der moralische Stolz, zu wissen, dass Sie das Richtige tun, helfen, Sie zu tragen durch.

BlairHippo
quelle
7

Zum einen sitze ich fast nie nur da und schreibe Unit-Tests. Unit Tests sind Mittel zum Zweck, kein Selbstzweck. Sie sind eine Möglichkeit zu beantworten, "ob dieser Code die Grundaufgabe erfüllt, die er erfüllen soll".

Zum Beispiel schreiben einige Leute eine Funktion und öffnen dann eine interaktive Sitzung, um sie an einigen Werten zu testen und sicherzustellen, dass sie funktioniert:

def fact x
  if x == 0
    1
  else 
    x * fact(x-1)
  end
end

>> fact 10
=> 3628800
>> fact 7
=> 5040

Aber jetzt entdeckst du einen Fehler:

>> fact -1
SystemStackError: stack level too deep
    from (irb):2:in `fact'
    from (irb):5:in `fact'
    from (irb):10

So beheben Sie es:

def fact x
  if x < 0
    raise "Can't take the factorial of a negative number"
  elsif x == 0
    1
  else 
    x * fact(x-1)
  end
end

>> fact -1
RuntimeError: Can't take the factorial of a negative number
    from (irb):3:in `fact'
    from (irb):10

Aber jetzt solltest du wirklich testen, ob es noch funktioniert:

>> fact 10
=> 3628800
>> fact 7
=> 5040

Wie Sie sehen, wiederholen Sie immer wieder dieselben Tests ... und müssen die Ergebnisse visuell vergleichen. Unit-Tests vermeiden in diesem Fall die Wiederholung. Es reduziert den Arbeitsaufwand. Und obwohl dies ein albernes kleines Beispiel ist, wird es in der realen Welt immer wichtiger und es wird immer schwieriger, manuell zu testen. Dies bedeutet natürlich, dass die einzelnen Komponenten einfach nicht getestet werden. Sie testen nur das gesamte Programm. Aber dann tauchen Käfer auf und sie sind viel schwerer zu finden. Oder es treten Fehler auf und sie sind behoben, aber jemand führt den gleichen Fehler erneut ein, weil niemand einen Testfall hinzugefügt hat, um sicherzustellen, dass dies nicht passiert ist. Oder jemand schaut sich ein großes Stück Code an und sagt: "Ich habe keine Ahnung, was dies tun soll, da es nicht dokumentiert ist und keine Tests hat ... Wenn ich diesen Fehler behebe, habe ich keine Ahnung, ob ich abhängig davon etwas anderes kaputt mache. Vielleicht schreibe ich das einfach von Grund auf neu. "

Unit-Tests reduzieren in diesen Fällen den gesamten Mehraufwand. Der beste Weg, ihnen Spaß zu machen, besteht darin, sicherzustellen, dass die Leute alle Arbeiten verstehen, die sie ersetzen, und die zusätzliche Flexibilität, die sich daraus ergibt, dass sie wissen, was jeder Code tun soll. Bis zu einem gewissen Grad müssen die Benutzer etwas mehr Erfahrung mit dem Schreiben und Verwalten einer großen Codebasis haben, um zu verstehen, wie wichtig Unit-Tests sein können. Wenn all ihr Code etwas ist, das sie einmal geschrieben und weggeworfen haben, werden sie ihn nie richtig verstehen.

Und Unit-Tests sollten nicht nachträglich geschrieben werden, da ein zusätzlicher Aufwand entsteht, sobald Sie Code haben, von dem Sie "wissen", dass er bereits funktioniert. Unit-Tests sollten zuerst oder zumindest (da Sie manchmal vergessen, sie zuerst zu schreiben) direkt nach dem Schreiben des fraglichen Codes geschrieben werden. Dies wird als testgetriebene Entwicklung bezeichnet und kann dazu beitragen, Ihre APIs zu verbessern. Wenn Sie zuerst die Tests schreiben, die die APIs testen, werden Sie lernen, wo die APIs zu verwenden sind, bevor Sie überhaupt den Code schreiben, und können viel einfacher umgestalten, als wenn Sie die Tests erst danach hinzufügen.

Brian Campbell
quelle
@Biran, ich stimme zu. Aber das alles macht es zum "richtigen" Ding. Aber wie macht man es angenehm? Auch etwas?
Preets
@Preets Es macht Spaß, weil Sie sich wiederholende manuelle Tests ersparen. Es macht mehr Spaß, wenn Sie es zuerst tun , als nachträglich, weil es Teil des Designprozesses wird und nicht nachträglich für Code, der bereits "funktioniert".
Brian Campbell
Also, Zeit damit verbringen, es schlecht zu machen, damit es im Vergleich dazu Spaß macht, es RICHTIG zu machen? ... Das könnte tatsächlich funktionieren ...
BlairHippo
@Biran, ich stimme zu, man muss es "zuerst" tun - nicht nur, um Langeweile zu beseitigen, sondern ich nehme an, dass es der richtige Weg ist, um die wahren Vorteile von Unit-Tests zu nutzen.
Preets
@Biran, danke! Ich habe TDD kürzlich für ein Hobbyprojekt von mir verwendet und es hat die Art und Weise, wie ich über Unit-Tests denke, verändert.
Preets
5

Ich weiß es nicht. Was Unit-Tests definitiv angenehmer macht, ist der Gedanke an all das frustrierende, langwierige, langweilige und unbelohnende Debugging, das ich nicht jedes Mal durchmachen muss, wenn ich eine Änderung an der Software vornehme :)

back2dos
quelle
2
Das ist interessant. Denn persönlich, wenn jemand einen Fehler in meinem Code findet, begrabe ich meinen Kopf in Schande, aber gleichzeitig ist der Prozess des Debuggens für mich ziemlich unterhaltsam und macht viel mehr Spaß als Unit-Tests. Es ist wie das Lösen eines Puzzles, bei dem Sie diesen hinterhältigen Fehler finden müssen.
Preets
@Preets: Ich stimme zu, manchmal kann es Spaß machen, aber für mich ist Design viel interessanter als die Implementierung. Daher verbringe ich nicht gerne viel Zeit mit der Implementierung. Ich bevorzuge es, direkt und vorhersehbar zu sein, vor allem, weil es zuverlässigere Zeitpläne ermöglicht. So gerne ich Software erstelle, so entscheidend finde ich das Ergebnis.
back2dos
Oh, da stimme ich voll und ganz zu! Ein System mit zufälligen Fehlern kann schlaflose Nächte verursachen. Meine Wahl war einfach eine Präferenz in einer unwirklichen Welt, in der nichts anderes als Spaß wichtig war!
Preets
3

Die selbstgefällige Überlegenheit, die Sie verspüren, wenn Sie Code einchecken, der solide, robust und stabil ist. Und wenn Sie Unit-Tests mit einem Code-Coverage-Tool schreiben, können Sie in Ihren Check-In-Kommentaren angeben, dass Ihre Code-Coverage 90% oder mehr beträgt.

C Johnson
quelle
3

Offensichtlich gibt es die Zufriedenheit der Test-First-Entwicklung und das Gefühl, wenn Ihr Design und Ihre Tests zusammenkommen. Das Schreiben von Tests für vorhandenen / älteren Code kann jedoch nervenaufreibend und frustrierend sein. Als sich unser Projekt in einem Wartungsmuster befand, schrieb ich Tests für ungetesteten Code unter Verwendung des Abdeckungsberichts als Spiel. Sie können eine Art Wettbewerb mit sich selbst und / oder anderen erstellen, um die Reichweite zu erhöhen. Zugegeben, Sie könnten zu weit gehen und einige schlechte Tests erstellen, aber es kann ein guter Motivator sein.

Matt H
quelle
Da Legacy-Code im Allgemeinen nicht leicht zu testen ist, habe ich Probleme, gute Komponententests zu schreiben - daher ist nicht nur der Prozess schmerzhaft, sondern auch das Ergebnis (Komponententests) ist nicht besonders nützlich: - / Das finde ich am frustrierendsten. Das Berichterstattungsspiel ist allerdings gut :)
Preets
1

Versuche in den Flow zu kommen . Setze dir harte, aber erreichbare Ziele. Was könnte ein Ziel im Unit-Test sein? Versuchen Sie beispielsweise, schneller zu schreiben und dabei die Qualität zu erhalten. Unit-Tests erfordern nicht zu viel Nachdenken, so dass Fehler unwahrscheinlich sind. Konzentrieren Sie sich auf Ihr Ziel und prüfen Sie regelmäßig, ob Sie sich dem Ziel nähern.

Tamás Szelei
quelle
ás, warum sagst du Unit-Test nicht zu viel Nachdenken? Wenn Sie mit TDD arbeiten, müssen Sie viel nachdenken. Ist das nicht wahr
Preets
Sie haben recht, ich habe TDD nicht berücksichtigt.
Tamás Szelei
0

Manchmal schreibe ich zu Beginn des Tages meine aktuelle "Code-Berichterstattung" auf, um mich zu motivieren. Jedes Mal, wenn ich einen Test schreibe und ihn bestehen lasse, starte ich die Suite und aktualisiere die Deckungsnummer. Es macht Spaß und hilft mir, daran zu erinnern, warum ich das tue. (Es gibt auch andere Gründe, aber ich mag die Zahlen. Vielleicht bin das nur ich!)

Marcie
quelle
0

Indem ich mir nicht vorstelle, ich könnte meinen Verstand täuschen, dass Unit-Tests für einen längeren Zeitraum Spaß machen können.

Zu akzeptieren, dass Unit-Tests nicht zum Genießen da sind, hilft mir sehr und macht mir klar, dass ich etwas an einem Ort suche, an dem es nie hätte sein sollen.

Bei diesen kurzen mentalen Exkursionen frage ich mich, ob ich es mir leisten kann, sie loszulassen, dh nicht zu haben, wenn ich Unit Testing als das empfinde, was es wirklich ist, dh eine grausame, unerträgliche und seelenzermürbende, langweilige Aufgabe Hohe Garantien für Funktionskorrektheit.

Die Antwort ist ausnahmslos ein klares "Nein".

Nachdem ich mein Schicksal akzeptiert habe, schiebe ich diese quadratischen Objekte mit Buchstaben, Zahlen und Symbolen vor mich her, die wir Tastatur nennen, da ich aus erster Hand weiß, dass mit jedem Tastenklick das Ende des Komponententests näher ist war schon mal .

Bugfoot
quelle
Nicht jeder Test ist gut oder nützlich. Dies ist etwas, das TDD'ers und andere Testevangelisten normalerweise nicht erwähnen. Ich wette, in einigen seltenen Momenten genießen Sie Unit-Tests, wenn Sie wissen, dass sie komplexe Logik testen, der Test elegant und nicht an die Implementierung gekoppelt ist und Sie es eher hassen, wenn Sie dazu gezwungen sind, Trivial-Mist zu testen, um nur ein verrücktes Ziel für die Codeabdeckung zu erreichen, das von gefordert wird Projektrichtlinien.
KolA
@KolA Sie haben Recht, dass es herausfordernde Komponententests gibt, die Kreativität erfordern, aber das Schreiben endloser Komponententests kann die Freude auch der von Natur aus interessanten herausfordern.
Bugfoot