Ich werde für Code bezahlt, der funktioniert, nicht für Tests. Meine Philosophie ist es daher, so wenig wie möglich zu testen, um ein bestimmtes Vertrauensniveau zu erreichen (ich vermute, dass dieses Vertrauensniveau im Vergleich zu Industriestandards hoch ist, aber das könnte nur Hybris sein). . Wenn ich normalerweise keinen Fehler mache (wie das Setzen der falschen Variablen in einem Konstruktor), teste ich nicht darauf. Ich neige dazu, Testfehler zu verstehen, daher bin ich besonders vorsichtig, wenn ich Logik mit komplizierten Bedingungen habe. Wenn ich in einem Team codiere, ändere ich meine Strategie, um Code sorgfältig zu testen, den wir gemeinsam tendenziell falsch machen.
Unterschiedliche Personen haben unterschiedliche Teststrategien, die auf dieser Philosophie basieren. Dies erscheint mir jedoch angesichts des unreifen Verständnisses, wie Tests am besten in die innere Codierungsschleife passen, vernünftig. In zehn oder zwanzig Jahren werden wir wahrscheinlich eine universellere Theorie haben, welche Tests zu schreiben sind, welche Tests nicht zu schreiben sind und wie man den Unterschied erkennt. In der Zwischenzeit scheint das Experimentieren angebracht.
Schreiben Sie Komponententests für Dinge, von denen Sie erwarten, dass sie brechen, und für Randfälle. Danach sollten Testfälle hinzugefügt werden, sobald Fehlerberichte eingehen - bevor das Update für den Fehler geschrieben wird. Der Entwickler kann dann sicher sein, dass:
Gemäß dem beigefügten Kommentar - Ich denke, dieser Ansatz zum Schreiben von Komponententests könnte Probleme verursachen, wenn im Laufe der Zeit viele Fehler in einer bestimmten Klasse entdeckt werden. Hier ist wahrscheinlich Diskretion hilfreich - Hinzufügen von Komponententests nur für Fehler, die wahrscheinlich erneut auftreten oder deren erneutes Auftreten ernsthafte Probleme verursachen würde. Ich habe festgestellt, dass ein Maß für Integrationstests in Komponententests in diesen Szenarien hilfreich sein kann - das Testen von Code in höheren Codepfaden kann die Codepfade weiter unten abdecken.
quelle
Eines der am meisten missverstandenen Dinge über TDD ist das erste Wort darin. Prüfung. Deshalb kam BDD. Weil die Leute nicht wirklich verstanden haben, dass das erste D das wichtige ist, nämlich Driven. Wir alle neigen dazu, ein bisschen zu viel über das Testen und ein bisschen zu wenig über das Fahren des Designs nachzudenken. Und ich denke, dass dies eine vage Antwort auf Ihre Frage ist, aber Sie sollten wahrscheinlich überlegen, wie Sie Ihren Code steuern, anstatt was Sie tatsächlich testen. Das ist etwas, bei dem Ihnen ein Coverage-Tool helfen kann. Design ist ein ziemlich größeres und problematischeres Thema.
quelle
Für diejenigen, die vorschlagen, "alles" zu testen: Stellen Sie fest, dass für das "vollständige Testen" einer solchen Methode
int square(int x)
etwa 4 Milliarden Testfälle in gängigen Sprachen und typischen Umgebungen erforderlich sind.In der Tat, es ist sogar noch schlimmer als das: ein Verfahren ,
void setX(int newX)
auch verpflichtet ist , nicht die Werte aller anderen Elemente außer zu verändernx
- testen Sie , dassobj.y
,obj.z
usw. alle bleiben unverändert nach dem Aufrufobj.setX(42);
?Es ist nur praktisch, eine Teilmenge von "alles" zu testen. Sobald Sie dies akzeptieren, wird es schmackhafter, nicht unglaublich einfaches Verhalten zu testen. Jeder Programmierer hat eine Wahrscheinlichkeitsverteilung der Fehlerstellen; Der intelligente Ansatz besteht darin, Ihre Energie auf Testregionen zu konzentrieren, in denen Sie die Fehlerwahrscheinlichkeit als hoch einschätzen.
quelle
Die klassische Antwort lautet "Teste alles, was möglicherweise kaputt gehen könnte". Ich interpretiere das so, dass das Testen von Setzern und Gettern, die nichts anderes als Setzen oder Erhalten tun, wahrscheinlich zu viel Testen ist, ohne sich die Zeit nehmen zu müssen. Wenn Ihre IDE diese nicht für Sie schreibt, können Sie dies auch tun.
Wenn Ihr Konstruktor, der keine Eigenschaften festlegt, später zu Fehlern führen kann, ist das Testen, dass diese festgelegt sind, kein Overkill.
quelle
Ich schreibe Tests, um die Annahmen der Klassen abzudecken, die ich schreiben werde. Die Tests erzwingen die Anforderungen. Wenn x beispielsweise niemals 3 sein kann, werde ich sicherstellen, dass es einen Test gibt, der diese Anforderung abdeckt.
Wenn ich keinen Test schreibe, um einen Zustand abzudecken, wird er immer später während "menschlicher" Tests auftauchen. Ich werde dann sicherlich eine schreiben, aber ich würde sie lieber früh fangen. Ich denke, der Punkt ist, dass das Testen (vielleicht) mühsam, aber notwendig ist. Ich schreibe genug Tests, um vollständig zu sein, aber nicht mehr.
quelle
Ein Teil des Problems beim Überspringen einfacher Tests besteht darin, dass durch das Refactoring diese einfache Eigenschaft in Zukunft mit viel Logik sehr kompliziert werden könnte. Ich denke, die beste Idee ist, dass Sie Tests verwenden können, um die Anforderungen für das Modul zu überprüfen. Wenn Sie beim Bestehen von X Y zurückerhalten sollten, möchten Sie dies testen. Wenn Sie den Code später ändern, können Sie überprüfen, ob X Ihnen Y gibt, und Sie können einen Test für A hinzufügen, der Ihnen B ergibt, wenn diese Anforderung später hinzugefügt wird.
Ich habe festgestellt, dass sich die Zeit, die ich während der ersten Entwicklung für das Schreiben von Tests verbringe, in der ersten oder zweiten Fehlerbehebung auszahlt. Die Möglichkeit, Code abzurufen, den Sie seit 3 Monaten nicht mehr angesehen haben, und einigermaßen sicher zu sein, dass Ihr Fix alle Fälle abdeckt und "wahrscheinlich" nichts kaputt macht, ist äußerst wertvoll. Sie werden auch feststellen, dass Unit-Tests dazu beitragen, Fehler weit über die Stapelverfolgung usw. hinaus zu ermitteln. Wenn Sie sehen, wie einzelne Teile der App funktionieren und fehlschlagen, erhalten Sie einen umfassenden Einblick, warum sie funktionieren oder als Ganzes fehlschlagen.
quelle
In den meisten Fällen würde ich sagen, wenn es dort Logik gibt, testen Sie sie. Dies schließt Konstruktoren und Eigenschaften ein, insbesondere wenn mehr als eine Sache in der Eigenschaft festgelegt wird.
In Bezug auf zu viele Tests ist es umstritten. Einige würden sagen, dass alles auf Robustheit getestet werden sollte, andere sagen, dass für effiziente Tests nur Dinge getestet werden sollten, die möglicherweise brechen (dh Logik).
Ich würde mich mehr auf das zweite Lager konzentrieren, nur aus persönlicher Erfahrung, aber wenn jemand beschließen würde, alles zu testen, würde ich nicht sagen, dass es zu viel war ... ein bisschen übertrieben vielleicht für mich, aber nicht zu viel für sie.
Also, nein - ich würde sagen, es gibt nicht so etwas wie "zu viele" Tests im allgemeinen Sinne, nur für Einzelpersonen.
quelle
Testgesteuerte Entwicklung bedeutet, dass Sie die Codierung beenden, wenn alle Ihre Tests bestanden wurden.
Wenn Sie keinen Test für eine Eigenschaft haben, warum sollten Sie ihn dann implementieren? Was sollte die Eigenschaft tun, wenn Sie das erwartete Verhalten im Falle einer "illegalen" Zuweisung nicht testen / definieren?
Deshalb bin ich total dafür, jedes Verhalten zu testen, das eine Klasse zeigen sollte. Einschließlich "primitiver" Eigenschaften.
Um diesen Test zu vereinfachen, habe ich eine einfache NUnit erstellt
TestFixture
, die Erweiterungspunkte zum Festlegen / Abrufen des Werts bereitstellt, Listen gültiger und ungültiger Werte erstellt und einen einzigen Test durchführt, um zu überprüfen, ob die Eigenschaft ordnungsgemäß funktioniert. Das Testen einer einzelnen Eigenschaft könnte folgendermaßen aussehen:Mit Lambdas und Attributen kann dies sogar kompakter geschrieben werden. Ich nehme an, MBUnit hat sogar native Unterstützung für solche Dinge. Der Punkt ist jedoch, dass der obige Code die Absicht der Eigenschaft erfasst.
PS: Wahrscheinlich sollte der PropertyTest auch eine Möglichkeit haben, zu überprüfen, ob sich andere Eigenschaften des Objekts nicht geändert haben. Hmm .. zurück zum Zeichenbrett.
quelle
Ich mache einen Unit-Test, um die maximal mögliche Abdeckung zu erreichen. Wenn ich keinen Code erreichen kann, überarbeite ich, bis die Abdeckung so vollständig wie möglich ist
Nachdem ich mit dem Blinding-Schreibtest fertig bin, schreibe ich normalerweise einen Testfall, der jeden Fehler reproduziert
Ich bin es gewohnt, zwischen Codetests und Integrationstests zu unterscheiden. Während des Integrationstests (der ebenfalls ein Komponententest ist, jedoch Gruppen von Komponenten, also nicht genau das, wofür ein Komponententest vorgesehen ist) werde ich testen, ob die Anforderungen korrekt implementiert werden.
quelle
Je mehr ich meine Programmierung durch das Schreiben von Tests vorantreibe, desto weniger mache ich mir Sorgen über den Grad der Granualität der Tests. Rückblickend scheint es, als würde ich das Einfachste tun, um mein Validierungsziel zu erreichen Verhalten zu . Dies bedeutet, dass ich eine Vertrauensschicht generiere, dass mein Code das tut, was ich verlange. Dies wird jedoch nicht als absolute Garantie dafür angesehen, dass mein Code fehlerfrei ist. Ich bin der Meinung, dass die richtige Balance darin besteht, das Standardverhalten und möglicherweise ein oder zwei Randfälle zu testen und dann mit dem nächsten Teil meines Entwurfs fortzufahren.
Ich akzeptiere, dass dies nicht alle Fehler abdeckt und verwende andere traditionelle Testmethoden, um diese zu erfassen.
quelle
Im Allgemeinen fange ich klein an, mit Ein- und Ausgängen, von denen ich weiß, dass sie funktionieren müssen. Wenn ich dann Fehler behebe, füge ich weitere Tests hinzu, um sicherzustellen, dass die von mir behobenen Fehler getestet werden. Es ist organisch und funktioniert gut für mich.
Kannst du zu viel testen? Wahrscheinlich, aber es ist wahrscheinlich besser, generell auf Nummer sicher zu gehen, obwohl dies davon abhängt, wie geschäftskritisch Ihre Anwendung ist.
quelle
Ich denke, Sie müssen alles in Ihrem "Kern" Ihrer Geschäftslogik testen. Getter ans Setter auch, weil sie negative Werte oder Nullwerte akzeptieren könnten, die Sie möglicherweise nicht akzeptieren möchten. Wenn Sie Zeit haben (immer von Ihrem Chef abhängig), ist es gut, andere Geschäftslogik und alle Controller, die diese Objekte aufrufen, zu testen (Sie wechseln langsam vom Komponententest zum Integrationstest).
quelle
Ich teste keine einfachen Setter / Getter-Methoden, die keine Nebenwirkungen haben. Aber ich teste jede andere öffentliche Methode. Ich versuche, Tests für alle Randbedingungen in meinen Algorthims zu erstellen und die Abdeckung meiner Unit-Tests zu überprüfen.
Es ist viel Arbeit, aber ich denke, es lohnt sich. Ich würde lieber Code schreiben (sogar Code testen), als Code in einem Debugger durchzugehen. Ich finde den Code-Build-Deploy-Debug-Zyklus sehr zeitaufwändig und je umfassender die Unit-Tests, die ich in meinen Build integriert habe, desto weniger Zeit verbringe ich mit diesem Code-Build-Deploy-Debug-Zyklus.
Sie haben nicht gesagt, warum Architektur Sie auch codieren. Aber für Java verwende ich Maven 2 , JUnit , DbUnit , Cobertura und EasyMock .
quelle
Je mehr ich darüber lese, desto mehr denke ich, dass einige Unit-Tests genau wie einige Muster sind: Ein Geruch von unzureichenden Sprachen.
Wenn Sie testen müssen, ob Ihr Trivial-Getter tatsächlich den richtigen Wert zurückgibt, liegt dies daran, dass Sie den Getter-Namen und den Namen der Mitgliedsvariablen miteinander mischen können. Geben Sie 'attr_reader: name' von Ruby ein, und das kann nicht mehr passieren. In Java einfach nicht möglich.
Wenn Ihr Getter jemals nicht trivial wird, können Sie trotzdem einen Test dafür hinzufügen.
quelle
Testen Sie den Quellcode, der Sie beunruhigt.
Ist nicht nützlich, um Teile des Codes zu testen, mit denen Sie sehr, sehr vertraut sind, solange Sie darin keine Fehler machen.
Testen Sie Bugfixes, damit Sie zum ersten und letzten Mal einen Bug beheben.
Testen Sie, um das Vertrauen in obskure Codeteile zu erhalten, damit Sie Wissen erstellen.
Testen Sie vor schwerem und mittlerem Refactoring, damit vorhandene Funktionen nicht beschädigt werden.
quelle
Diese Antwort dient eher dazu, herauszufinden, wie viele Komponententests für eine bestimmte Methode verwendet werden sollen, von der Sie wissen, dass Sie sie aufgrund ihrer Kritikalität / Wichtigkeit testen möchten. Mit der Basis Path Testing- Technik von McCabe können Sie Folgendes tun, um quantitativ ein besseres Vertrauen in die Codeabdeckung zu erzielen als mit der einfachen "Anweisungsabdeckung" oder "Zweigabdeckung":
quelle