Zeitunterschied zwischen der Entwicklung mit Unit-Tests und ohne Tests

132

Ich bin ein Einzelentwickler mit einer ziemlich zeitlich begrenzten Arbeitsumgebung, in der die Entwicklungszeit normalerweise zwischen 1 und 4 Wochen pro Projekt liegt, abhängig von den Anforderungen, der Dringlichkeit oder beiden. Zu einem bestimmten Zeitpunkt bearbeite ich ungefähr 3-4 Projekte, von denen einige überlappende Zeitleisten haben.

Erwartungsgemäß leidet die Codequalität. Ich habe auch keine formalen Tests; Es geht normalerweise so lange durch das System, bis es etwas bricht. Infolgedessen kann eine beträchtliche Anzahl von Fehlern in die Produktion gelangen, die ich beheben muss, und die wiederum meine anderen Projekte zurücksetzen.

Hier kommen Unit-Tests ins Spiel. Wenn alles richtig gemacht wird, sollten die Fehler, geschweige denn die, die in die Produktion flüchten, auf ein Minimum reduziert werden. Auf der anderen Seite kann das Schreiben von Tests viel Zeit in Anspruch nehmen, was sich bei zeitlich begrenzten Projekten wie meinem nicht gut anhört.

Die Frage ist, wie viel Zeitunterschied das Schreiben von Unit-Test-Code gegenüber ungetestetem Code bedeuten würde, und wie weitet sich dieser Zeitunterschied mit zunehmendem Projektumfang aus?

Wiederauferstandener
quelle
Kommentare sind nicht für eine längere Diskussion gedacht. Diese Unterhaltung wurde in den Chat verschoben .
maple_shaft
8
Sie lösen das falsche Problem. Sie sind zu beschäftigt und scheinen keine Unterstützung für das Projektmanagement zu haben. Schätzen Sie den Projektaufwand? Buchen Sie 20% Ihrer Zeit für Fehlerkorrekturen, Besprechungen und andere nicht codierende Aufgaben? Wie viel Überstunden machst du?
Tony Ennis
20
Ist Ihnen klar, dass Sie im Wesentlichen sagen: "Ich habe Zeit, es zweimal zu tun, aber keine Zeit, es einmal richtig zu tun."
RubberDuck
5
@RubberDuck Es gibt tatsächlich einen Punkt in der Kurve der Projektkomplexität, gemessen als Zeit zum Schreiben vs. Zeit zum Testen, wobei "zweimal wringen" weniger Zeit benötigt als "Schreiben und Testen". Ich denke, es kann irgendwo in der Region eines Bash Oneliner sein.
Lyndon White
Einmal bekamen die Entwickler Geschenke und dankten, als ein Projekt abgesagt wurde. Ich wies darauf hin , dass wir selbst hätten mehr produktiv waren wir bekannt , dass das Produkt nicht versenden würde. Dies ist also ein Fall, in dem das Entwickeln ohne Testen vorteilhaft wäre.
JDługosz

Antworten:

149

Je später Sie testen, desto mehr kostet es, Tests zu schreiben.

Je länger ein Fehler lebt, desto teurer ist die Behebung.

Das Gesetz der sinkenden Rendite stellt sicher, dass Sie sich selbst in Vergessenheit geraten lassen und sicherstellen können, dass es keine Bugs gibt.

Buddha lehrte die Weisheit des Mittelwegs. Tests sind gut. Es gibt so etwas wie zu viel Gutes. Der Schlüssel ist in der Lage zu erkennen, wenn Sie aus dem Gleichgewicht sind.

Jede Codezeile, die Sie ohne Tests schreiben, verursacht erheblich höhere Kosten für das Hinzufügen von Tests, als wenn Sie die Tests vor dem Schreiben des Codes geschrieben hätten.

Jede Codezeile ohne Tests ist erheblich schwieriger zu debuggen oder neu zu schreiben.

Jeder Test, den Sie schreiben, braucht Zeit.

Es wird einige Zeit dauern, bis jeder Fehler behoben ist.

Die Gläubigen werden Ihnen sagen, dass Sie keine einzige Codezeile schreiben sollen, ohne zuerst einen nicht bestandenen Test zu schreiben. Der Test stellt sicher, dass Sie das Verhalten erhalten, das Sie erwarten. Damit können Sie den Code schnell ändern, ohne sich Gedanken über Auswirkungen auf den Rest des Systems machen zu müssen, da der Test beweist, dass das Verhalten dasselbe ist.

Sie müssen all das gegen die Tatsache abwägen, dass Tests keine Funktionen hinzufügen. Produktionscode fügt Funktionen hinzu. Und Funktionen sind das, was die Rechnungen bezahlen.

Pragmatisch gesehen füge ich alle Tests hinzu, mit denen ich durchkommen kann. Ich ignoriere Kommentare zugunsten von Tests. Ich vertraue nicht einmal Code zu tun, was ich denke, dass es tut. Ich vertraue Tests. Aber ich war bekannt dafür, dass ich gelegentlich Hagelwurf mache und Glück habe.

Viele erfolgreiche Codierer führen jedoch keine TDD durch. Das heißt nicht, dass sie nicht testen. Sie bestehen einfach nicht darauf, dass jede Codezeile einen automatisierten Test hat. Selbst Onkel Bob gibt zu, dass er seine Benutzeroberfläche nicht testet. Er besteht auch darauf, dass Sie die gesamte Logik aus der Benutzeroberfläche entfernen.

Als Fußballmetapher (das ist American Football) ist TDD ein gutes Grundspiel. Nur manuelles Testen, bei dem Sie eine Menge Code schreiben und hoffen, dass es funktioniert, ist ein vorübergehendes Spiel. Sie können entweder gut sein. Ihre Karriere wird die Playoffs nicht schaffen, wenn Sie nicht beides können. Erst wenn Sie wissen, wann Sie welche auswählen müssen, wird das Superbowl zu etwas Besonderem werden. Aber wenn Sie einen Schubs in eine bestimmte Richtung brauchen: Die Beamten rufen mich häufiger an, wenn ich vorbeigehe.

Wenn Sie TDD ausprobieren möchten, empfehle ich dringend, dass Sie üben, bevor Sie versuchen, es bei der Arbeit zu tun. TDD auf halbem Weg gemacht, halbherzig und halbherzig ist ein wichtiger Grund, warum manche es nicht respektieren. Es ist, als würde man ein Glas Wasser in ein anderes gießen. Wenn Sie sich nicht festlegen und es schnell und vollständig tun, träufeln Sie am Ende Wasser über den Tisch.

kandierte_orange
quelle
68
Es gibt so etwas wie viel Gutes Weder Sie noch Buddha haben die Kekse meiner Großmutter getestet :-)
Pierre Arlaud
3
@ NickAlexeev Ich liebe das Diagramm dort. Eine Sache, auf die es nicht hinweist, ist, dass Unit-Tests (die normalerweise automatisiert sind) wirklich gut darin sind, Fehler zu finden, wenn der Code geändert wird. Ich würde gerne sehen, wie sich das in "Bugs, die vor der Veröffentlichung gefunden wurden" und "Bugs, die nach der Veröffentlichung gefunden wurden" aufteilt. Unit-Tests sind die beste Verteidigungslinie gegen Regression.
corsiKa
3
Ich halte das für eine sehr ausgewogene Antwort: Es kann Zeitverschwendung sein, alles zu testen, auch Kleinigkeiten. Gute Tests für die komplexen Teile, die leicht brechen können, können wirklich hilfreich sein. Ich habe gerade ein kleines, aber nicht triviales Projekt von Java nach C ++ portiert. Ich habe zuerst die Tests portiert und dadurch die gesamte C ++ - Implementierung eingerichtet. Nachdem alle Tests grün waren, mussten nur einige einfachere Klassen portiert werden, und es lief ziemlich reibungslos. Andererseits habe ich keine Tests für den gesamten Code: Dies hätte die Implementierung mit geringem Gewinn um mindestens 3, 4 Tage verlängert.
Giorgio
5
Ein kleiner Widerspruch dazu: „Sie müssen das alles gegen die Tatsache abwägen, dass Tests keine Merkmale hinzufügen. Code fügt Funktionen hinzu. Und Funktionen sind es, die die Rechnungen bezahlen. ' Ich würde stark empfehlen, dass es nicht Funktionen sind, die die Rechnungen bezahlen - es sind funktionierende Funktionen. (oder werden die Leute für nicht funktionierende Leistungen bezahlt?) Den Rest der Antwort stimme ich voll und ganz zu.
Tony Suffolk 66
6
@ TonySuffolk66 Du hast Recht, es sind die Funktionen, die die Rechnungen bezahlen (außer Flimflam Salesmanship). Die Leute haben jedoch schon lange vor TDD Funktionen entwickelt. Sie werden lange, nachdem es weg ist. Denken Sie daran, TDD ist eine disziplinierte Methode zum Testen. Es ist nicht die einzige disziplinierte Art zu testen.
candied_orange
112

Ich stimme dem Rest der Antworten zu, aber um die Frage nach dem Zeitunterschied direkt zu beantworten .

Roy Osherove hat in seinem Buch The Art of Unit Testing, zweite Ausgabe, Seite 200 eine Fallstudie durchgeführt, in der Projekte ähnlicher Größe mit ähnlichen Teams für zwei verschiedene Kunden implementiert wurden, bei denen ein Team Tests durchführte und das andere nicht.

Seine Ergebnisse waren wie folgt:

Teamfortschritt und Leistung gemessen mit und ohne Tests

Am Ende eines Projekts treten also sowohl weniger Zeit als auch weniger Fehler auf. Das hängt natürlich davon ab, wie groß ein Projekt ist.

Aki K
quelle
32
Die Stichprobe ist viel zu klein, um dies als wissenschaftlich zu betrachten, aber ich denke, sie ist repräsentativ für das, was viele Menschen erleben. Wenn ich TDD mache, wird der größte Teil der zusätzlichen Zeit für die Behebung der Fehler aufgewendet, die dazu führen, dass meine Komponententests fehlschlagen, und nicht für das Schreiben der Tests. Das erhöht nicht wirklich die zusätzliche Zeit, sondern verschiebt sich nur, wenn Sie diese Probleme finden und beheben. Jede echte Verlängerung besteht darin, Probleme zu beheben, die Sie nicht gefunden hätten, zumindest nicht im ersten Durchgang.
JimmyJames
7
@JimmyJames Es handelt sich um eine Fallstudie, die häufig in der Wirtschaft und in der Wissenschaft verwendet wird, wenn es (noch) nicht möglich ist, ein reproduzierbares Experiment in großem Maßstab durchzuführen. Es gibt Psychologie-Fachzeitschriften, die voll davon sind. "Unwissenschaftlich" ist nicht das richtige Wort.
Djechlin
25
Warum denke ich, wenn das Ergebnis dieser Fallstudie das Gegenteil gezeigt hätte, wäre es nicht in das Buch gekommen ;-)?
Doc Brown
11
@ DocBrown Ich frage mich, wie viele Fallstudien gemacht und verworfen wurden, bevor sie eine mit den richtigen Antworten fanden :-)
gbjbaanb
6
@ JimmyJames, die mit ziemlicher Sicherheit als Wissenschaft qualifiziert. Außerdem kann ein anderer Wissenschaftler diese Fallstudie "n = 1" lesen, entscheiden, ob es sich lohnt, mehr zu studieren, dann eine groß angelegte statistische Studie oder sogar ein kontrolliertes Experiment in Längsrichtung durchführen und sie bestätigen oder ablehnen. Genau so funktioniert Wissenschaft. So soll es funktionieren. Weitere Informationen zur Funktionsweise der Wissenschaft finden Sie hier: en.wikipedia.org/wiki/Scientific_method
djechlin
30

Ich kenne nur eine Studie, die dies in einer "realen Umgebung" untersucht hat: Qualitätsverbesserung durch testgetriebene Entwicklung: Ergebnisse und Erfahrungen von vier Industrieteams . Es ist teuer, dies auf vernünftige Weise zu tun, da es im Grunde bedeutet, dass Sie dieselbe Software zweimal (oder im Idealfall sogar öfter) mit ähnlichen Teams entwickeln und dann alle außer einem wegwerfen müssen.

Die Ergebnisse der Studie waren eine Verlängerung der Entwicklungszeit zwischen 15% und 35% (was nicht annähernd der von TDD-Kritikern häufig angegebenen 2-fachen Zahl entspricht) und eine Verringerung der Defektdichte vor der Freigabe von 40% auf 90% (! ). Es ist zu beachten, dass alle Teams keine Erfahrung mit TDD hatten, sodass man davon ausgehen konnte, dass der Zeitanstieg zumindest teilweise auf das Lernen zurückzuführen ist und daher im Laufe der Zeit noch weiter sinken würde, was von der Studie jedoch nicht bewertet wurde.

Beachten Sie, dass es in dieser Studie um TDD geht und dass es sich bei Ihrer Frage um Unit-Tests handelt, bei denen es sich um sehr unterschiedliche Dinge handelt, die mir jedoch am nächsten kommen.

Jörg W. Mittag
quelle
1
Es wäre interessanter, zusätzliche Einschränkungen aufzuerlegen: Kein veränderlicher Zustand nach SOLID, statische Typisierung, kein Verlassen auf null, Funktionieren über Imperativ, Codeverträge, statische Analyse, automatisches Refactoring, keine IoC-Container (aber DI) usw. Ich wette diesen Wert der Unit-Tests würde abnehmen (aber nicht verschwinden).
Den
24

Gut gemacht, kann die Entwicklung mit Komponententests schneller sein, auch ohne die Vorteile von Extras zu berücksichtigen, die beim Erkennen von Fehlern auftreten.

Tatsache ist, dass ich nicht gut genug bin, um meinen Code einfach arbeiten zu lassen, sobald er kompiliert ist. Wenn ich Code schreibe / ändere, muss ich den Code ausführen, um sicherzustellen, dass er das tut, was ich dachte. Bei einem Projekt sah das so aus:

  1. Code ändern
  2. Anwendung kompilieren
  3. Anwendung ausführen
  4. Melden Sie sich bei der Anwendung an
  5. Öffne ein Fenster
  6. Wählen Sie ein Element aus diesem Fenster aus, um ein anderes Fenster zu öffnen
  7. Stellen Sie in diesem Fenster einige Steuerelemente ein und klicken Sie auf eine Schaltfläche

Und natürlich dauerte es nach all dem normalerweise ein paar Hin- und Rückfahrten, um es richtig zu machen.

Was ist, wenn ich Unit-Tests verwende? Dann sieht der Prozess eher so aus:

  1. Schreibe einen Test
  2. Führen Sie Tests durch und vergewissern Sie sich, dass diese in der erwarteten Weise fehlschlagen
  3. Code schreiben
  4. Führen Sie die Tests erneut durch und stellen Sie sicher, dass sie erfolgreich sind

Dies ist einfacher und schneller als das manuelle Testen der Anwendung. Ich muss die Anwendung immer noch manuell ausführen (damit ich nicht albern aussehe, wenn ich eine Arbeit einreiche, die eigentlich gar nicht funktioniert), aber zum größten Teil habe ich die Probleme bereits behoben, und ich bin es nur Überprüfung an diesem Punkt. Normalerweise mache ich diese Schleife noch enger, indem ich ein Programm verwende, das meine Tests beim Speichern automatisch wiederholt.

Dies hängt jedoch davon ab, ob Sie in einer testfreundlichen Codebasis arbeiten. Viele Projekte, auch solche mit vielen Tests, erschweren das Schreiben von Tests. Wenn Sie jedoch daran arbeiten, können Sie über eine Codebasis verfügen, die durch automatisierte Tests einfacher zu testen ist als durch manuelle Tests. Als Bonus können Sie die automatisierten Tests beibehalten und ausführen, um Regressionen zu vermeiden.

Winston Ewert
quelle
1
Und wenn Sie so etwas wie nCrunch verwenden, können Sie die Schritte 2 und 4 kürzen, wodurch die Rückkopplungsschleife noch enger wird.
Euphorischer
"Ich muss die Anwendung noch manuell ausführen" ist eine wichtige Beobachtung, IMHO. Keine silbernen Kugeln.
Den
20

Obwohl es bereits viele Antworten gibt, wiederholen sie sich etwas und ich würde gerne eine andere Richtung einschlagen. Unit-Tests sind nur dann wertvoll, wenn sie den Unternehmenswert steigern . Das Testen zu Testzwecken (triviale oder tautologische Tests) oder um eine beliebige Metrik (wie die Codeabdeckung) zu treffen, ist Frachtkultprogrammierung.

Tests sind kostspielig, nicht nur in der Zeit, in der sie geschrieben werden müssen, sondern auch in der Wartung. Sie müssen mit dem Code, den sie testen, synchron gehalten werden, oder sie sind wertlos. Ganz zu schweigen von den Zeitkosten, die bei jeder Änderung anfallen. Dies ist kein Deal-Breaker (oder eine Entschuldigung dafür, nicht die wirklich notwendigen zu machen), sondern muss bei der Kosten-Nutzen-Analyse berücksichtigt werden.

Bei der Frage, ob (oder in welcher Form) eine Funktion / Methode getestet werden soll, sollten Sie sich also die Frage stellen, welchen Endbenutzerwert ich mit diesem Test erzeuge / absichere. Wenn Sie diese Frage nicht beantworten können, weg von der Oberseite des Kopfes , dann ist das Test wahrscheinlich nicht wert , die Kosten des Schreibens / aufrechterhalten wird . (oder Sie nicht verstehen , die Problem - Domäne, die eine ist waaaay größeres Problem als ein Mangel an Tests).

http://rbcs-us.com/documents/Why-Most-Unit-Testing-is-Waste.pdf

Jared Smith
quelle
1
Ich bin mit BDD nicht besonders vertraut, werde aber vermuten, dass es mit einer etwas gröberen Granularität als die Methoden- / Funktionsebene arbeitet und wahrscheinlich eine weniger schwache Verbindung zum Benutzerwert hat.
Jared Smith
1
Related
Robbie Dee
9
"Testen um des Testens willen (triviale oder tautologische Tests) oder um eine willkürliche Metrik (wie Codeabdeckung) zu treffen, ist Frachtkultprogrammierung." So wahr und so gut gesagt. Testen Sie so, dass Sie sich wie ein cooler Arsch fühlen - denken Sie an sich selbst als ... Spion, Spitzensportler ... Testen Sie NICHT wie eine "Regierungsbehörde". Wissen Sie?
Fattie
2
@SteveJessop nicht einverstanden, Code-Coverage (im Sinne einer Metrik) ist von Natur aus willkürlich: Die Anzahl der Pfade durch ein nicht-triviales Programm auf der Ebene der Maschinenanweisungen (dh dasjenige, das zählt) ist größer als die Anzahl der Atome auf Erde oder möglicherweise sogar das sichtbare Universum. Dies ist nicht testbar. Jeder Anspruch auf 'Code-Abdeckung' wird also auf einen heuristisch gewählten willkürlichen Schwellenwert beschränkt sein. Programmierer sind gut darin, solche Metriken auf Kosten der Dinge zu spielen, die wirklich wichtig sind.
Jared Smith
2
Ich würde auch sagen, dass Tests ungefähr (wenn auch nicht genau) einen geschäftlichen Nutzen bringen, wenn sie fehlschlagen, und die Lösung darin besteht, den getesteten Code zu verbessern. Wenn Sie also TDD verwenden, geschieht dies so ziemlich automatisch, mindestens einmal pro Test. Tautologische Tests können per Definition nicht scheitern und sind daher unbrauchbar. Für "triviale" Tests - Nachdem ich zu Beginn meiner Karriere mit dem Java TCK gearbeitet habe, wundere ich mich nicht mehr darüber, wie trivial ein Test sein kann, wenn eine API von Grund auf neu implementiert wird fast immer heuristisch vorausgesagt, also auch "willkürlich".
Steve Jessop
9

Dies hängt von der Person sowie der Komplexität und Form des Codes ab, mit dem Sie arbeiten.

Bei den meisten Projekten bedeutet das Schreiben von Komponententests für mich, dass ich die Arbeit etwa 25% schneller erledige. Ja, einschließlich der Zeit, um die Tests zu schreiben.

Weil die Tatsache ist, dass Software nicht fertig ist, wenn Sie den Code schreiben. Dies geschieht, wenn Sie es an den Kunden versenden und dieser damit zufrieden ist. Unit-Tests sind bei weitem die effizienteste Methode, die ich kenne, um die meisten Fehler zu erkennen, die meisten Fehler zum Debuggen zu isolieren und das Vertrauen zu gewinnen, dass der Code gut ist. Sie müssen diese Dinge sowieso tun, also machen Sie sie gut.

Telastyn
quelle
7
Ich denke, es ist erwähnenswert, es ist eine erworbene Fähigkeit. Ich sehe, dass so viele Leute die Behauptung hören, dass TDD im Voraus nicht einmal eine Zeitersparnis ist, die sich auf lange Sicht auszahlt, sondern nur schneller. dann versuchen sie es für einen Tag und es ist schmerzhaft, weil sie 0 Erfahrung haben, 0 Bücher gelesen haben, keine Übung, sie erwarten nur, dass es magisch funktioniert. Es gibt kein Geheimnis für TDD, das Sie zu einem besseren Entwickler macht. Sie müssen immer noch üben, müssen immer noch nachdenken und müssen immer noch gut fundierte Entscheidungen treffen.
Sara
1
@ kai - +1. Ich habe wochenlang über TDD gelesen, bevor ich es ausprobiert habe. Ich habe alles gelesen, was ich finden konnte. Ich lese Bücher. Ich habe alle bekannten agilen Blogs durchgelesen, um Beispiele zu finden. Ich lese die xUnit-Testmuster von vorne bis hinten. In den ersten Wochen habe ich immer noch doppelt so lange gebraucht.
Jules
2
Genau. TDD ist schwer. Die Denkweise ist schwierig. Jeder, der sagt "Schreiben Sie einfach die Tests zuerst" und behauptet, dass es kostenlos ist, weiß nicht, wie es geht. Es braucht Übung.
Duffymo
@kai: Aus ähnlichen Gründen können viele Leute nicht tippen. Sie versuchten es einmal und tippten nach einer ganzen Stunde immer noch nicht schneller als zuvor ;-)
Steve Jessop
@SteveJessop Ich denke, das ist ein ziemlich guter Vergleich. Oder wirklich untauglich zu sein und 10 Minuten joggen zu gehen, erschöpft zu werden und sich zu fragen, warum man nicht in einer Stunde 10 Meilen laufen kann. Es zeigt wirklich, wie Sie arbeiten müssen, bevor Sie die Vorteile nutzen können.
Sara
4

Die Frage ist, wie viel Zeitunterschied das Schreiben von Unit-Test-Code gegenüber ungetestetem Code bedeuten würde, und wie weitet sich dieser Zeitunterschied mit zunehmendem Projektumfang aus?

Das Problem verschlimmert sich mit zunehmendem Alter des Projekts: Wenn Sie neue Funktionen hinzufügen und / oder vorhandene Implementierungen überarbeiten, müssen Sie erneut testen, was zuvor getestet wurde, um sicherzustellen, dass es weiterhin funktioniert. Für ein langlebiges (mehrjähriges) Projekt müssen Sie möglicherweise nicht nur die Funktionalität testen, sondern sie 100-mal und öfter erneut testen. Aus diesem Grund können Sie von automatisierten Tests profitieren . IMO ist es jedoch gut genug (oder sogar besser), wenn es sich um automatisierte Systemtests handelt und nicht um automatisierte Komponententests.

Ein zweites Problem ist, dass es schwieriger ist, Fehler zu finden und zu beheben, wenn sie nicht frühzeitig entdeckt werden. Wenn sich beispielsweise ein Fehler im System befindet und ich weiß, dass er einwandfrei funktioniert hat, bevor Sie Ihre letzte Änderung vorgenommen haben, konzentriere ich meine Aufmerksamkeit auf Ihre letzte Änderung, um zu sehen, wie der Fehler möglicherweise aufgetreten ist. Aber wenn ich nicht weiß, dass das System funktioniert hat, bevor Sie Ihre letzte Änderung vorgenommen haben (weil das System vor Ihrer letzten Änderung nicht ordnungsgemäß getestet wurde), kann der Fehler an einer beliebigen Stelle auftreten.

Das Obige gilt insbesondere für Deep Code und weniger für flachen Code, z. B. das Hinzufügen neuer Webseiten, wenn neue Seiten wahrscheinlich keine Auswirkungen auf vorhandene Seiten haben.

Infolgedessen kann eine beträchtliche Anzahl von Fehlern in die Produktion gelangen, die ich beheben muss, und die wiederum meine anderen Projekte zurücksetzen.

Nach meiner Erfahrung wäre das inakzeptabel und Sie stellen die falsche Frage. Anstatt zu fragen, ob Tests die Entwicklung beschleunigen würden, sollten Sie sich fragen, was die Entwicklung fehlerfreier machen würde.

Eine bessere Frage könnte sein:

  • Sind Unit-Tests die richtige Art von Tests, um die "beträchtliche Menge an Fehlern", die Sie produziert haben, zu vermeiden?
  • Gibt es andere Qualitätskontroll- / Verbesserungsmechanismen (abgesehen von Unit-Tests), die ebenfalls oder stattdessen empfohlen werden?

Lernen ist ein zweistufiger Prozess: Lernen Sie, es gut genug zu machen, und lernen Sie dann, es schneller zu machen.

ChrisW
quelle
3

Einige Aspekte zu berücksichtigen, nicht in den anderen Antworten erwähnt.

  • Zusatznutzen / Zusatzkosten hängen von der Erfahrung mit dem Schreiben von Unittests ab
    • Mit meinem ersten Unit-Test-Projekt haben sich die Mehrkosten verdreifacht, weil ich viel lernen musste und viele Fehler gemacht habe.
    • nach 10 jahren erfahrung mit tdd benötige ich 25% mehr codierzeit, um die tests vorab zu schreiben.
  • mit mehr tdd-modulen sind noch manuelle gui-tests und integrationstests nötig
  • tdd funktioniert nur von Anfang an.
    • Das Anwenden von tdd auf ein bestehendes, gewachsenes Projekt ist teuer / schwierig. Sie können jedoch stattdessen Regressionstests implementieren.
  • Für automatisierte Tests (Unittests und andere Tests) ist eine Wartungskonstante erforderlich, damit sie funktionieren.
    • Das Erstellen von Tests durch Kopieren und Einfügen kann die Wartung von Testcodes verteuern.
    • Mit zunehmender Erfahrung wird Testcode modularer und einfacher zu warten.
  • mit zunehmender erfahrung bekommen sie das gefühl, wann es sich lohnt, automatisierte tests zu erstellen und wann nicht.
    • Beispiel: Es ist kein großer Vorteil, einfache Getter / Setter / Wrapper zu entfernen
    • Ich schreibe keine automatisierten Tests über die GUI
    • ich sorge dafür, dass der businesslayer getestet werden kann

Zusammenfassung

Wenn Sie mit tdd beginnen, ist es schwierig, den Status "Mehr Nutzen als Kosten" zu erreichen, solange Sie sich in einem "zeitlich begrenzten Arbeitsumfeld" befinden, insbesondere wenn es "clevere Manager" gibt, die Ihnen sagen, dass Sie "die teuren, nutzlosen" loswerden sollen Sachen testen "

Hinweis: Mit "Komponententest" meine ich "Module isoliert testen".

Hinweis: Mit "Regressionstests" meine ich

  • Schreiben Sie Code, der einen Ausgabetext erzeugt.
  • Schreiben Sie einen "Regressionstest" -Code, der bestätigt, dass das Ergebnis der Generierung immer noch dasselbe ist.
  • Der Regressionstest informiert Sie, wann immer sich das Ergebnis ändert (was in Ordnung sein könnte oder ein Indikator für einen neuen Fehler).
  • Die Idee des "Regressionstests" ähnelt Genehmigungsprüfungen
    • ... machen Sie einen Schnappschuss der Ergebnisse und bestätigen Sie, dass sie sich nicht geändert haben.
k3b
quelle
Benötigt Korrekturlesen (das literarische Äquivalent zum Testen?)
JDługosz
3

Programmierer unterschätzen, wie Menschen, die sich mit den meisten Aufgaben befassen, wie lange es tatsächlich dauert, diese zu erledigen. Unter diesem Gesichtspunkt kann ein Zeitaufwand von 10 Minuten für das Schreiben eines Tests als Zeitaufwand für das Schreiben von Tonnen von Code angesehen werden, während Sie in Wirklichkeit dieselbe Zeit damit verbracht hätten, denselben Funktionsnamen und dieselben Parameter wie während des Tests zu entwickeln . Dies ist ein TDD-Szenario.

Tests nicht zu schreiben, ist wie eine Kreditkarte zu haben; Wir neigen dazu, mehr Geld auszugeben oder mehr Code zu schreiben. Mehr Code hat mehr Fehler.

Anstatt sich für eine vollständige oder gar keine Codeabdeckung zu entscheiden, empfehle ich, sich auf den kritischen und komplizierten Teil Ihrer Anwendung zu konzentrieren und dort Tests durchzuführen. In einer Banking-App kann dies die Zinsberechnung sein. Ein Motordiagnose-Tool verfügt möglicherweise über komplexe Kalibrierungsprotokolle. Wenn Sie an einem Projekt gearbeitet haben, wissen Sie wahrscheinlich, was es ist und wo die Fehler sind.

Beginnen Sie langsam. Bauen Sie etwas Geläufigkeit auf, bevor Sie urteilen. Sie können immer aufhören.

JeffO
quelle
3

Es gibt eine lange Geschichte von Programmierern, die TDD und andere Testmethoden bewerben. Ich werde mich nicht an ihre Argumente erinnern und ihnen zustimmen.

  • Das Testen ist je nach Kontext nicht so bequem und effizient. Ich entwickle Web-Software, sage mir, ob Sie ein Programm zum Testen der gesamten Benutzeroberfläche haben ... Im Moment programmiere ich Excel-Makros. Sollte ich wirklich ein Testmodul in VBA entwickeln?
  • Das Schreiben und Warten der Testsoftware ist eine echte Arbeit, die auf kurze Sicht zählt (sie zahlt sich auf lange Sicht aus). Das Schreiben relevanter Tests ist auch eine Expertise
  • Wenn Sie als Team arbeiten und alleine arbeiten, müssen Sie nicht dieselben Testanforderungen erfüllen, da Sie im Team Code validieren, verstehen und kommunizieren müssen, den Sie nicht geschrieben haben.

Ich würde sagen, dass das Testen gut ist, aber stellen Sie sicher, dass Sie früh testen und prüfen, wo der Gewinn liegt.

Arthur Havlicek
quelle
1
"Soll ich wirklich ein Testmodul für VBA entwickeln?" Verdammt richtig, das solltest du. rubberduckvba.com/Features#unitTesting
RubberDuck
Es gibt ein paar Gründe, warum ich dies nicht benutze, weil es nicht meinen Bedürfnissen entspricht (ich bin an höchstens ein paar Tagen mit Aufgaben beschäftigt, die Umgebung ist gesperrt, Nachfolger werden Dritte nicht belästigen). Guter Kommentar, Sprache ist an sich keine Entschuldigung :)
Arthur Havlicek
Alle Messepunkte @ArthurHavlicek.
RubberDuck
2
Das Schreiben von Tests ist in VBA noch trivial. Mit all den ausgefallenen Funktionen, die einige unitteste Frameworks haben? Das ist schwieriger, aber ein Programm mit dem Namen mainTest(), das alle Testmodule aufruft, auszuführen, ist nicht wirklich schwierig.
Enderland
1

Ein oft übersehener Vorteil von TDD ist, dass die Tests als Schutz dienen, um sicherzustellen, dass Sie bei Änderungen keine neuen Fehler einführen.

Der TDD-Ansatz ist anfangs zweifellos zeitaufwändiger, aber der springende Punkt ist, dass Sie weniger Code schreiben , was bedeutet, dass weniger Dinge schief gehen. All diese Schnickschnack, die Sie oft einbauen, schaffen es natürlich nicht in die Codebasis.

Es gibt eine Szene im Film Swordfish, in der ein Hacker mit einer Waffe an seinem Kopf arbeiten muss, um sich zu erinnern, und ansonsten abgelenkt wird. Der Punkt ist, dass es viel einfacher ist zu arbeiten, wenn sich Ihr Headspace im Code befindet und Sie Zeit auf Ihrer Seite haben, anstatt Monate später, wenn ein Kunde Sie anschreit und andere Prioritäten gequetscht werden.

Entwickler verstehen, dass das Beheben von Fehlern später teurer ist, aber drehen Sie das auf den Kopf. Wenn Sie 500 US-Dollar pro Tag für die Codierung Ihres aktuellen Codes oder 1000 US-Dollar für die TDD-Codierung erhalten könnten, würden Sie der Person, die Ihnen das zweite Angebot unterbreitet, die Hand abbeißen. Je eher Sie das Testen nicht mehr als lästige Pflicht ansehen und es als Geldsparer ansehen, desto besser ist es für Sie.

Robbie Dee
quelle
Das Ding in deinem ersten Satz heißt Regressionstest
Katze
0

Ich kann mich auf Ihre Erfahrung beziehen - unsere Codebasis hatte fast keine Tests und war größtenteils nicht testbar. Es dauerte buchstäblich eine Ewigkeit, um etwas zu entwickeln, und die Behebung von Produktivitätsfehlern kostbare Zeit für neue Funktionen.

Für eine teilweise Umschreibung habe ich mir geschworen, Tests für alle Kernfunktionen zu schreiben. Anfangs dauerte es erheblich länger und meine Produktivität litt merklich, aber danach war meine Produktivität besser als je zuvor.

Ein Teil dieser Verbesserung war, dass ich weniger Produktionsfehler hatte, was wiederum zu weniger Unterbrechungen führte -> ich hatte zu jeder Zeit einen besseren Fokus.

Darüber hinaus zahlt sich die Fähigkeit aus, Code isoliert zu testen UND zu debuggen - eine Reihe von Tests ist einem System, das nur mit manueller Einrichtung debuggt werden kann, bei weitem überlegen, z ein paar Dutzend Mal

Beachten Sie jedoch, dass die Produktivität zu Beginn abnimmt. Beginnen Sie also mit dem Testen eines Projekts, bei dem der Zeitdruck noch nicht verrückt ist. Versuchen Sie auch, es in einem Projekt auf der grünen Wiese zu starten. Das Testen älterer Codes durch Unit-Tests ist sehr schwierig. Es ist hilfreich, wenn Sie wissen, wie eine gute Testsuite aussieht.

Christian Sauer
quelle
0

Nur um vorherige Antworten zu ergänzen: Denken Sie daran, dass das Testen selbst kein Zweck ist. Der Zweck von Tests besteht darin, dass sich Ihre Anwendung im Verlauf der Evolution in unerwarteten Kontexten usw. erwartungsgemäß verhält.

Schreiben von Tests bedeutet daher nicht, alle Verhaltensweisen aller Endpunkte einer Entität zu beweisen. Dies ist ein häufiger Fehler. Viele Entwickler denken, dass sie alle Funktionen / Objekte / Methoden / Eigenschaften / etc testen müssen. Dies führt zu einer hohen Arbeitsbelastung und einer Reihe irrelevanter Codes und Tests. Dieser Ansatz ist bei großen Projekten üblich, bei denen sich die meisten Entwickler des ganzheitlichen Verhaltens nicht bewusst sind, sondern nur ihren Interaktionsbereich sehen können.

Der richtige Ansatz beim Umgang mit sparsamen Ressourcen und beim Testen ist ziemlich offensichtlich und vom gesunden Menschenverstand, aber nicht allgemein formalisiert: Investieren Sie die Ressourcen für die Testentwicklung zunächst in Funktionen auf hoher Ebene und gehen Sie schrittweise in Besonderheiten über . Das bedeutet, dass Sie sich als einsamer Entwickler irgendwann nicht nur auf Unit-Tests konzentrieren, sondern auch auf Funktionen / Integration / etc. Testen und je nach Ihren Zeitressourcen schrittweise in die wichtigsten einheitlichen Funktionen, wie Sie planen und berücksichtigen würden. Übergeordnete Tests bieten die erforderlichen Informationen, um übergeordnete / einheitliche Tests abzuwickeln und Ihre Testentwicklungsstrategie anhand der verfügbaren Ressourcen zu planen.

Beispielsweise möchten Sie eine Verarbeitungskette zunächst als Blackbox testen. Wenn Sie feststellen, dass ein Mitglied der Kette aufgrund eines Verhaltens ausfällt, bei dem ein extremer Zustand nicht berücksichtigt wurde, schreiben Sie die Tests, die die Funktionalität nicht nur für dieses Mitglied, sondern auch für andere garantieren. Dann liefern Sie. Im nächsten Zyklus stellen Sie fest, dass das Netzwerk manchmal ausfällt. Sie schreiben also Tests, die sich mit solchen Problemen befassen, auf die Module, die anfällig sein könnten. Und so weiter.

RodolfoAP
quelle