Wie groß muss mein Projekt sein, damit ich es testen kann? [geschlossen]

86

Ich gehe davon aus, dass mein Projekt ausreichend entkoppelt ist, um Unit-Tests zu ermöglichen. Aber wie groß muss mein Projekt in Bezug auf Klassen und Funktionen genau sein, damit sich das Testen von Einheiten lohnt?

Wir alle machen Fehler und niemand ist perfekt, aber ich betrachte mich als einen anständigen Programmierer, um die Fehler kleiner Projekte beim Durchstarten zu bewältigen. Oder ist Unit-Testing eine harte Notwendigkeit, egal wie groß Ihr Projekt ist?

Lamin Sanneh
quelle
26
Die große falsche Annahme, die Sie machen, ist, dass das Projekt nur für Sie ist und dass es nur für den Augenblick ist . Was ist, wenn Sie es für ein paar Monate stehen lassen, etwas anderes tun und dann darauf zurückkommen? Werden Sie das gleiche Vertrauen haben, ein "anständiger Programmierer" zu sein (was nichts damit zu tun hat, ob Sie testen wollen oder nicht)? Was ist, wenn jemand anderes Ihr Projekt übernimmt? Ein großartiger Blogger (der leider nicht mehr aktiv ist) schrieb , man solle sich immer "um den Codeleser kümmern, nicht um den Codeschreiber".
Amos M. Carpenter
6
Wie wäre es damit (für C # .NET): int x = 3 * (1/3); Was wird nach Abschluss der Operation in x gespeichert? Mein Punkt ist, dass sogar ein Zeilencode getestet werden muss, da dies zu einem Fehler führen kann, entweder weil Sie es nicht wissen oder weil Sie wissen, dass Sie aber den falschen Code ausgeführt haben.
NoChance
2
@aaamos, ich denke du vermisst meinen Standpunkt. Die Tatsache, dass mir nur diese Frage gestellt wird, zeigt, dass ich in Betracht ziehe, auch den Codeleser zu bedienen.
Lamin Sanneh
13
Nachdem Sie dies in beide Richtungen getan haben, kann ich Ihnen sagen, dass es so viel einfacher ist, die Tests zu schreiben, während Sie fortfahren (dh während das Projekt klein ist), als zurückzugehen und später Komponententests zu schreiben, wenn Sie der Meinung sind, dass das Projekt auf eine willkürliche Grundlage gestoßen ist. " Wir sollten jetzt Tests schreiben "Bedingung.
Wonko the Sane
1
Sie stellen die falsche Frage. Es ist egal, wie groß das Projekt ist. Die Frage ist, wie viel kümmert es dich, wenn es richtig ist? Wenn Korrektheit wichtig ist, sind Unit-Tests ein wirksames Mittel, um die Korrektheit zu verbessern.
Mark E. Haase

Antworten:

206

Ihr Projekt ist bereits groß genug.

Nach meiner Erfahrung waren eine Klasse und eine Funktion ausreichend, um die Notwendigkeit von Komponententests zu berücksichtigen.

    class Simple {
        boolean reallySimple() {
            return true; // how do we make sure it doesn't change to false?
        }
    }


    class SimpleTest {
        void assertReallySimple() {
            // ensure reallySimple return value isn't changed unexpectedly
            UnitTestFramework.assertTrue(new Simple().reallySimple());
        }
    }
Mücke
quelle
24
Sicherlich sollten Sie früher beginnen, am Funktionspunkt 0 class / 0 ... wenn Sie TDD folgen :)
Kaz Dragon
115
+1. Wenn Ihr Programm groß genug ist, um Fehler zu haben, ist es groß genug, um Komponententests durchzuführen.
Jason Orendorff
9
@JasonOrendorff: Ich verspotte das in ein Poster und bringe es in mein Büro. Brillant.
Justin ᚅᚔᚈᚄᚒᚔ
Zusätzlich ermöglicht es ein "sicheres" Refactoring.
Timo
7
Ich bin zwar nicht unbedingt mit dem Gefühl anderer Meinung, aber wenn Ihr Code wirklich so einfach ist, könnten Sie wahrscheinlich nur mit Behauptungen davonkommen, anstatt mit vollständigen Komponententests.
Chuu
109

Ich habe mich noch nie für die Idee "Du musst alles testen" entschieden, obwohl es sicherlich Leute gibt, die das getan haben (siehe die Antwort der Mücke !).

Für mich sind die Hauptvorteile von Unit-Tests:

  1. Helfen Sie dabei, sicherzustellen, dass Änderungen nichts ändern.
  2. Hilft Ihnen beim Entwerfen sinnvoller Schnittstellen zu Ihren Klassen (da Sie gezwungen sind, ein Client für Ihren eigenen Code zu sein).
  3. Hilft zu dokumentieren, wie Ihr Code voraussichtlich verwendet wird.

Grundsätzlich müssen Sie die Zeit abwägen, die Sie benötigen, um Tests gegen diese Faktoren zu schreiben und aufrechtzuerhalten.

Nummer 1 reicht normalerweise aus, um es sich zu lohnen, Tests zu schreiben. Nach meiner Erfahrung werden über 95% des Codes früher oder später geändert.

vaughandroid
quelle
8
Stimmen Sie dem zu - wenn Sie in einem einzelnen Entwicklergeschäft arbeiten, müssen Sie ein Gleichgewicht zwischen Softwarequalität und dem Testen von allem herstellen (was viel Zeit in Anspruch nehmen kann). Vergessen Sie nicht , dass jedes Mal wenn Sie eine Änderung vornehmen müssen Sie Ihre Unit - Tests zu Anzug ändern
Matt Wilko
1
Sie sollten nicht alles testen, aber Sie sollten jedes Verhalten testen, das der Außenwelt ausgesetzt ist. Das Testen ist mit Wartungskosten verbunden, und wie Kent Beck in einer SO-Antwort sagte (ich glaube, es war SO) - testen Sie genug, um sicherzugehen, dass Ihr Code korrekt ist.
Wayne Werner
10
Ich würde hinzufügen, dass Unit-Tests die falsche Zielebene sind, wenn Sie nur minimale automatisierte Tests durchführen. Gehen Sie stattdessen zu Integrations- / Rauch-Tests auf hoher Ebene, bei denen ein paar Datensätze durch Ihre App geleitet werden, ohne etwas zu verspotten. Sie möchten, dass diese Tests so viel von Ihrer Codebasis wie möglich beanspruchen und alle normalen Anwendungsfälle und Ausführungspfade abdecken. Eine Wahrscheinlichkeit von 75%, dass Ihre Änderungen irgendwo in der App einen Fehler verursacht haben, ist vorteilhafter als eine Wahrscheinlichkeit von 5%, dass Sie SomeClass.OneOfTheHandfulOfTestedFunctions () verursacht haben.
Dan Neely
3
Äh, ich glaube, Sie haben einen verpasst: "Stellen Sie sicher, dass der Code so funktioniert, wie er soll!"
BlueRaja - Danny Pflughoeft
3
@ BlueRaja-DannyPflughoeft: Eigentlich wäre es genauer zu sagen: "Sicherstellen, dass der Code die von Ihnen geschriebenen Komponententests besteht!"
Vaughandroid
34

Es ist ganz einfach: Sie müssen keine Unit-Tests durchführen, wenn Sie das Programm nach einmaliger Ausführung verwerfen möchten.

Wenn Ihnen dies übertrieben erscheint, überlegen Sie, was die Alternative bedeuten würde. Wenn es eine Größe gäbe, unter der sich Unit-Tests nicht auszahlen, müssten Sie sich immer wieder überlegen: "Habe ich die magische Größe schon erreicht? Soll ich anfangen, Tests zu schreiben?" Jetzt sind Programmierer bekanntermaßen schlecht darin, die Zukunft vorherzusagen, und sie sind bekanntermaßen schlecht darin, ihre eigenen Fähigkeiten einzuschätzen. Code, der für Sie jetzt kristallklar aussieht, wird selbst für Sie unverständlich, selbst wenn Sie einen Monat warten. Ein Projekt, von dem Sie absolut sicher sind, dass es nie wieder verwendet wird, und bei dem Sie lediglich die entfernte Chance haben, nachzuschlagen, wie Sie etwas zuvor gelöst haben, wird erneut angefordert und es werden Änderungsanforderungen empfangen.

Es ist daher sehr wahrscheinlich, dass Sie falsch einschätzen, ob das Testen hilfreich ist oder nicht, und wenn Sie anfangen, Tests zu benötigen, sind Sie sich bereits nicht hundertprozentig sicher, welche Semantik tatsächlich zu testen ist. Da ich der Meinung bin, dass alle Programme mit Ausnahme trivialer Einmalprogramme von Unit-Tests profitieren, halte ich die Kosten für die Ausgaben für Tests, die nie wieder ausgeführt werden, für vernachlässigbar, da das Risiko besteht, nicht getesteten und nicht verstandenen Code zu erweitern.

Kilian Foth
quelle
22
Programmierer sind notorisch schlecht darin, ihre eigenen Fähigkeiten zur Vorhersage der Zukunft
einzuschätzen
3
@superM Ich stimme dir zu. Das Programm "Einmal ausführen und wegwerfen", das ich bereits während meiner kurzen Karriere geschrieben habe, blieb alle paar Tage bestehen und wurde geschäftskritisch. Ich nenne das das "temporäre", auch bekannt als der temporär-permanente Effekt ...
seufz
@Jalayn Ist die Antwort nicht einfach, dass man zurückgehen und Unit-Tests hinzufügen sollte, sobald diese Erkenntnis greift?
Cornel Masson
@CornelMasson Sie haben absolut Recht, erwarten Sie, dass es oft schwierig ist, Manager davon zu überzeugen, dass "es noch nicht fertig ist", weil Tests fehlen :-)
Jalayn
@ Jalayn: Zu wahr!
Cornel Masson
22

Vor einiger Zeit habe ich einen schönen Beitrag gefunden: Warum Unit-Tests die Entwicklung beschleunigen . Es kann Ihnen helfen, die Frage zu beantworten.

... Was wäre, wenn die Codebasis ... mit einem umfangreichen Satz von Komponententests versehen wäre? Ein Satz, der sagen würde: „Wenn alle Tests erfolgreich sind , garantiere ich , dass Code immer noch tut , was es tun sollte , “ und wenn ein Test fehlschlägt es genau zeigt Ihnen , wo einige Verhalten gebrochen ist. Das ist großartig, ich könnte den Code ändern, um Dinge hinzuzufügen, die ich möchte, ohne zu wandern, wenn der Code immer noch das tut, was er tun soll. Ich führe nur die ... Tests aus und ich habe Vertrauen. Dies ist eine großartige Welt, in der man als Softwareentwickler sein kann. Mir ist aufgefallen, dass ich viel schneller vorankommen kann ...

Ich habe Vertrauen".

Dies ist wahrscheinlich der wichtigste Grund, warum Unit-Tests die Entwicklung im Unternehmenskontext beschleunigen.

Ich kann darauf vertrauen, dass alles noch funktioniert, wenn alle Tests erfolgreich sind. Wenn die Tests fehlschlagen, zeigen sie genau, wo das Problem liegt ...

... Sie müssen eine hohe Einheitentestabdeckung und gute Einheitentests haben . Wenn diese Bedingungen eingehalten werden, werden Sie feststellen, dass der Aufwand für das Hinzufügen neuer Funktionen fast unabhängig von der Größe der Anwendung ist und auf lange Sicht die Entwicklung beschleunigt .

Michael Feathers hat in einem seiner Bücher zwei Möglichkeiten vorgestellt, mit Änderungen im Code zu arbeiten:

  • redigieren sie und beten sie,
  • abdecken und modifizieren.

Es spielt keine Rolle, wie groß die Codebasis ist.

Marcin Sanecki
quelle
18

Laut Kent Beck in seiner Antwort auf die Frage zum Stapelüberlauf Wie tief sind Ihre Komponententests? , sollten Sie den Code testen, den Sie tendenziell falsch machen.

Wenn ich normalerweise keinen Fehler mache (wie das Setzen der falschen Variablen in einem Konstruktor), teste ich nicht darauf.

Mansuro
quelle
4
Guter Punkt, und dies impliziert, dass die Frage des OP falsch ist; ob zu testen hat nichts mit der größe des projekts zu tun. Bei einer 5-Zeilen-Codebasis sind möglicherweise Tests erforderlich, bei einer 1-Zeilen-Methode in einer großen Codebasis möglicherweise nicht (obwohl dies bei anderen Elementen in dieser Codebasis der Fall ist).
Nathan Long
Dies funktioniert möglicherweise für kleine Projekte, an denen Sie alleine arbeiten, aber für ein Projekt, das entweder für die Arbeit (bei der Sie nicht kontrollieren können, wer in Zukunft daran arbeiten wird) oder für Open Source-Projekte, die Sie benötigen alles testen. Und Sie müssen sofort
loslegen,
@xaxxon: Kent spricht tatsächlich darüber in derselben Antwort, mit der Mansuro in Verbindung gebracht hat: "Wenn ich in einem Team programmiere, ändere ich meine Strategie, um den Code sorgfältig zu testen, der zusammengenommen häufig falsch ist."
Henko
Nein, das ist immer noch unglaublich kurzsichtig. Sie können nicht wissen, wer in Zukunft an dem Code arbeiten wird. Dies ist die Art von Denkweise, die junge Entwickler betrifft.
xaxxon
5

Unit-Tests werden durchgeführt, um Zeit zu sparen und Folgendes zu verbessern:

  • Bug-Tracking
  • Refactoring und / oder Neuschreiben von Code
  • Integrationstests
  • Regressionstests usw.

Es ist ein Muss, Komponententests für relativ komplexe Teile des Programms zu schreiben.

Wenn Sie sicher sind, dass das Schreiben von Unit-Tests in Zukunft keine Zeit spart, können Sie es überspringen. Sie werden es jedoch nie wissen, und ich persönlich kann mir keinen Fall vorstellen, in dem es günstiger ist (in Bezug auf Zeit, Geld und Nerven), Unit-Tests nicht zu schreiben, sondern alle Tests manuell durchzuführen.

superM
quelle
Generell eine gute Antwort, also +1. Ich denke jedoch, dass Ihr letzter Punkt die Tatsache verfehlt, dass Sie Ihre Komponententests immer noch manuell testen möchten / müssen!
Vaughandroid
@Baqueta, vielleicht habe ich mich nicht klar angehört, aber ich wollte nicht sagen, dass
Komponententests
4

"Sollte ich dies einmal testen" kann in der Regel durch Beantwortung der folgenden Frage beantwortet werden: "Ist es wichtig, dass diese Funktion ordnungsgemäß funktioniert, und ist es wichtig zu wissen, wann sie nicht mehr funktioniert?"

Natürlich ist es viel komplizierter, aber das ist ein guter Anfang. Schließlich werden Sie auch abwägen, ob der Code bereits getestet wird, weil er in einer anderen Funktion verwendet wird, oder ob Ihre Zeit besser für eine andere Funktion verwendet wird usw.

Bryan Oakley
quelle
4

Wenn Sie keinen Code schreiben, ohne ihn zu testen, fallen immer die Kosten für das Testen an.

Der Unterschied zwischen Unit-Tests und Nicht-Unit-Tests ist der Unterschied zwischen den Kosten für das Schreiben und Ausführen des Tests und den Kosten für das manuelle Testen.

Wenn die Kosten für das Schreiben eines Komponententests 2 Minuten betragen und die Kosten für das Ausführen des Komponententests praktisch 0 betragen, die Kosten für das manuelle Testen des Codes jedoch 1 Minute betragen, können Sie den Break Even erzielen, wenn Sie den Test zweimal ausgeführt haben.


Viele Jahre lang hatte ich das Missverständnis, dass ich nicht genug Zeit hatte, Komponententests für meinen Code zu schreiben. Wenn ich Tests schrieb, waren sie aufgebläht, schwere Dinge, die mich nur ermutigten zu glauben, dass ich Komponententests nur schreiben sollte, wenn ich wusste, dass sie gebraucht wurden.

Vor kurzem wurde ich ermutigt, Test Driven Development zu verwenden, und ich fand es eine vollständige Offenbarung. Ich bin jetzt fest davon überzeugt, dass ich nicht die Zeit habe, Unit-Tests nicht zu schreiben .

Wenn Sie mit Blick auf das Testen entwickeln, erhalten Sie meiner Erfahrung nach sauberere Schnittstellen, fokussiertere Klassen und Module und im Allgemeinen mehr SOLIDEN , testbaren Code.

Jedes Mal, wenn ich mit Legacy-Code arbeite, für den es keine Komponententests gibt, und ich etwas manuell testen muss, denke ich, dass dies viel schneller gehen würde, wenn für diesen Code bereits Komponententests vorhanden wären. Jedes Mal, wenn ich versuchen muss, dem Code mit hoher Kopplung Unit-Test-Funktionen hinzuzufügen, denke ich, dass dies so viel einfacher wäre, wenn er entkoppelt geschrieben worden wäre.


TL; DR- Version:

Schreiben Sie einen Test, wenn die Kosten für das Schreiben des Tests und die Kosten für das Ausführen des Tests so oft wie nötig geringer sind als die Kosten für das manuelle Testen so oft wie nötig.

Denken Sie jedoch daran, dass bei Verwendung von TDD die Kosten für das Schreiben von Tests wahrscheinlich sinken, je besser Sie darin sind. Wenn der Code nicht absolut trivial ist, werden Sie Ihre Tests wahrscheinlich häufiger ausführen als erwartet.

Mark Booth
quelle
3

Testen Sie , sobald Sie beobachten, dass Regressionen auftreten oder befürchten, dass einige durch Ihre Änderungen verursacht werden und Sie dies nicht bemerken.

Zünden Sie diese Angst an, lassen Sie es auf eine angemessene Größe anwachsen: Je früher Sie testen, desto besser.

Bitte beachten Sie: Abhängig von Ihrer Rolle im Projekt sind Unit-Tests möglicherweise nicht die einzige Art von Tests, die Sie schreiben möchten.

Jeder ist zu Recht von Unit-Tests besessen , weil in der Vergangenheit schlechte Mainstream-Testpraktiken praktiziert wurden. Aber wenn Sie noch nie zuvor getestet haben, sollten Sie sich wirklich auf das Testen im Allgemeinen konzentrieren . Unit-Tests allein werden die Probleme der Welt nicht lösen.

ZJR
quelle
1
Ich sehe, Sie zeigen, aber es ist keine Einheit, die den Grundstartpunkt für Startprogrammierer testet. Und könnten Sie auch genauer erläutern, was Sie unter "Testen im Allgemeinen" verstehen? Vielen Dank.
Lamin Sanneh
1
Es gibt mindestens zwei andere Arten von Tests - Integrationstests und Abnahmetests. Unit-Tests decken eine bestimmte Unit ab (z. B. soll diese Funktion dieser Klasse den Fizz fräsen). Sie verspotten alle anderen Stellen, an denen diese Klasse interagiert, und übergeben sie an gefälschte Daten. Wenn Sie Integrationstests durchführen, kombinieren Sie zwei (oder mehr) Klassen, um sicherzustellen, dass Ihre Klassen wie gewünscht zusammenpassen. Schließlich bauen Sie genug Tests auf, um Ihr gesamtes System durchgängig zu testen, manchmal auch als "Rauch-Tests" bezeichnet.
Wayne Werner
Es gibt auch Regressionstests vor Gericht. Regressionstests sind in der Regel größer als Komponententests, können einen Tag in Anspruch nehmen und den Zugriff auf Testdaten und spezielle Testumgebungen implizieren. Tatsächlich handelt es sich bei den Komponententests um kleinere, elegantere und besser zu wartende Versionen von (alten) Regressionstests.
ZJR
1

Ich glaube, dass es nicht die Größe des Projekts ist, sondern die Art des Projekts, die entscheidet, ob es getestet werden soll oder nicht.

Wenn Sie an einem Proof of Concept oder an einem anderen Projekt arbeiten, bei dem das Ziel darin besteht, aus dem Coding zu lernen, ist ein Testen nicht erforderlich. Wenn das Projekt verwendet, vielleicht sogar in die Produktion geschickt werden soll, sollte es getestet werden.

Ein Zitat aus Robert C. Martins "Clean Code" : "Wenn es trivial ist zu schreiben, ist es trivial zu testen", es gibt also keine Entschuldigung, das Testen für kurze und triviale Programme zu überspringen.

Eivind Eidheim Elseth
quelle
0

Es ist wirklich keine Frage der Größe - es ist, was Sie damit machen (und wie alt es ist). Wenn ich mich damit beschäftige, zu lernen, wie eine Technologie funktioniert, und vorhabe, das Ding wegzuwerfen (wir nennen dies eine Spitze in Scrum), codiere ich einfach, ohne viel zu testen. Wenn Sie vorhaben, es weiterzuentwickeln (auch wenn Sie nur herumschnüffeln), sollten Sie Tests um den Code schreiben. TDD ist eine Konstruktionstechnik, noch bevor es eine Prüftechnik ist. Sie möchten ein klares Bild davon haben, was der Code tun soll, bevor Sie mit den Einzelheiten der Ausführung vertraut werden. Würde ich auch NICHTEs wird empfohlen, umfangreiche Komponententests mit großen Mengen an Legacy-Code zu schreiben. Versuchen Sie, die Teile zu identifizieren, die komplex sind (mit einer hohen zyklomatischen Komplexität / Spaghetti-Code-Gefühl), und die Teile, die häufig ausfallen (sie sind häufig gleich). Wie andere vorgeschlagen haben, würde ich Kent Becks Buch über TDD lesen und auf jeden Fall Michael Feders Buch lesen. Was sie nicht besonders behandeln, ist der politische Aspekt beim Schreiben von Unit-Tests rund um Code. Viele Entwickler hassen es, ihren Code ändern zu müssen, um ihn testbar zu machen, und viele Entwickler haben nicht das Bedürfnis, Code überhaupt zu testen. Daran müssen wir als Beruf arbeiten. Alle anderen Ingenieurdisziplinen müssen (häufig mathematisch) nachweisen, dass ihre Arbeit den Spezifikationen entspricht. Wir sollten das Gleiche tun.

John Dahle
quelle
-1

Es kann falsch sein, ein Projekt in Klassen- oder Funktionsgrenzen zu binden und dann zu beurteilen, ob dies für Unit-Tests geeignet ist. Es gibt zahlreiche Vorteile des Unit-Testens einer Anwendung, aber echte Schönheit beginnt, wenn Sie eine Anwendung warten oder in einer verteilten Umgebung arbeiten müssen. Die Wahl kommt also hierher. Selbst eine kleine Änderung Ihres Codes kann zu Katastrophen führen.
Ich würde nicht nur "Unit Testing" vorschlagen, sondern auch empfehlen, die Codeabdeckung zu überprüfen, um sicherzustellen, dass der maximale Umfang Ihres Codes durch Unit Test abgedeckt wird. Der Schwellenwert für die Codeabdeckung darf 95% nicht unterschreiten, und das Ziel muss bei 100% liegen . Sie können Tools verwenden, um die Codeabdeckung zu verfolgen und einen Bericht zu erstellen.
Visual Studio stellt Abdeckungsdaten bereit -http://msdn.microsoft.com/en-us/library/ms182496(v=vs.80).aspx
Sie können auch NCover oder dotCover verwenden.

Niks
quelle