Wann ist es angebracht, keinen Komponententest durchzuführen?

138

Ich arbeite in einer kleinen Firma als Solo-Entwickler. Ich bin der einzige Entwickler im Unternehmen. Ich habe mehrere (relativ) große Projekte, die ich regelmäßig geschrieben und gepflegt habe, und keines hat Tests, um sie zu unterstützen. Wenn ich neue Projekte beginne, frage ich mich oft, ob ich einen TDD-Ansatz ausprobieren soll. Es klingt nach einer guten Idee, aber ich kann die zusätzliche Arbeit ehrlich gesagt nie rechtfertigen.

Ich arbeite hart, um in meinem Design zukunftsorientiert zu sein. Mir ist klar, dass sicherlich eines Tages ein anderer Entwickler meinen Code warten oder zumindest Fehler beheben muss. Ich halte die Dinge so einfach wie möglich und kommentiere und dokumentiere Dinge, die schwer zu begreifen sind. Und die Tatsache ist, dass diese Projekte nicht so groß oder kompliziert sind, dass ein anständiger Entwickler Schwierigkeiten haben würde, sie zu verstehen.

Viele der Beispiele, die ich bei Tests gesehen habe, betreffen alle Aspekte des Codes. Da ich der einzige Entwickler bin und dem Code im gesamten Projekt sehr nahe bin, ist es viel effizienter, ein Schreib- als auch ein manuelles Testmuster zu befolgen. Ich stelle auch fest, dass sich Anforderungen und Funktionen häufig genug ändern, um bei der Beibehaltung von Tests einen erheblichen Aufwand für ein Projekt zu verursachen. Zeit, die sonst für die Lösung der geschäftlichen Anforderungen aufgewendet werden könnte.

So komme ich jedes Mal zu dem gleichen Schluss. Die Kapitalrendite ist zu niedrig.

Ich habe gelegentlich ein paar Tests eingerichtet, um sicherzustellen, dass ich einen Algorithmus richtig geschrieben habe, wie zum Beispiel die Anzahl der Jahre, die jemand im Unternehmen war, basierend auf dem Einstellungsdatum. Aber vom Standpunkt der Codeabdeckung aus habe ich ungefähr 1% meines Codes abgedeckt.

Würden Sie in meiner Situation immer noch einen Weg finden, Unit-Tests zu einer regelmäßigen Praxis zu machen, oder bin ich berechtigt, diesen Aufwand zu vermeiden?

UPDATE: Einige Dinge über meine Situation, die ich ausgelassen habe: Meine Projekte sind alle Webanwendungen. Um meinen gesamten Code abzudecken, müsste ich automatisierte UI-Tests verwenden, und in diesem Bereich sehe ich immer noch keinen großen Vorteil gegenüber manuellen Tests.

Ken Pespisa
quelle
1
Vielen Dank an alle. Ich lerne hier viel. Ein paar Dinge über meine Situation, die ich ausgelassen habe: Meine Projekte sind alle Webanwendungen. Um meinen gesamten Code abzudecken, müsste ich automatisierte UI-Tests verwenden, und in diesem Bereich sehe ich immer noch keinen großen Vorteil gegenüber manuellen Tests.
Ken Pespisa
1
Wir haben große Erfolge bei Transactis mit dem Web-Automatisierungstest-Tool von Telerik. Wir haben bereits Dutzende früherer manueller Browsertests auf Automatisierung umgestellt. Die automatisierten Tests sind wesentlich schneller und sind auch sehr hilfreich, um Leistungsprobleme auf Ihrer Website hervorzuheben.
John Kaster
2
Ich habe ein Projekt gesehen, bei dem versucht wurde, komplette Webseiten automatisch über einen Browser zu testen. Soweit ich das beurteilen kann, hat es keinen der Hunderte schwerwiegender Fehler gefunden, die wir durch manuelle Tests gefunden haben, und die Entwicklung und Wartung hat enorm viel Zeit gekostet. (Verwendung von Selen, angetrieben von NUnit). Schlimmer noch, einige der Tests werden aufgrund von Inkompatibilitäten mit Browsern und Testframeworks häufig wegen Nichtproblemen abgebrochen.
O'Rooney
1
Dies ist nicht wirklich eine Antwort, nur eine Beobachtung ... Ihr Argument gegen Unit-Tests, weil "Anforderungen ändern sich zu häufig" mich an das umgekehrte Argument erinnert, das ich dort höre, wo ich arbeite: "Unsere Programme sind so statisch, was ist der Sinn des Testens es ändert sich sowieso fast nie! " ;)
Bane
2
Automatisierte UI-Tests von Webanwendungen sind keine Komponententests, sie sind ein ganz anderes Biest, und ich würde Ihnen keine Vorwürfe machen, wenn Sie sie nicht ausführen möchten. Ihr gesamter Geschäftscode sollte sich jedoch im Backend befinden, und das sollten Sie testen.
Nyamiou The Galeanthrope

Antworten:

84

Viele der Beispiele, die ich bei Tests gesehen habe, betreffen alle Aspekte des Codes.

Damit? Sie müssen nicht alles testen . Nur die relevanten Dinge.

Da ich der einzige Entwickler bin und dem Code im gesamten Projekt sehr nahe bin, ist es viel effizienter, ein Schreib- als auch ein manuelles Testmuster zu befolgen.

Das ist eigentlich falsch. Effizienter geht es nicht. Es ist wirklich nur eine Gewohnheit.

Was andere Solo-Entwickler tun, ist eine Skizze oder einen Umriss zu schreiben, die Testfälle zu schreiben und dann den Umriss mit dem endgültigen Code auszufüllen.

Das ist sehr, sehr effizient.

Ich stelle auch fest, dass sich Anforderungen und Funktionen häufig genug ändern, um bei der Beibehaltung von Tests einen erheblichen Aufwand für ein Projekt zu verursachen.

Das ist auch falsch. Die Tests sind nicht der Widerstand. Die Änderungen der Anforderungen sind der Widerstand.

Sie müssen die Tests korrigieren, um die Anforderungen widerzuspiegeln. Ob ihre minutiae oder High-Level; zuerst geschrieben oder zuletzt geschrieben.

Der Code wird erst nach Bestehen der Tests ausgeführt. Das ist die universelle Wahrheit von Software.

Sie können einen begrenzten "Here it is" -Abnahmetest durchführen.

Oder Sie können einige Unit-Tests haben.

Oder Sie können beides haben.

Aber egal was Sie tun, es gibt immer einen Test, um zu demonstrieren, dass die Software funktioniert.

Ich würde vorschlagen, dass ein bisschen Formalität und eine nette Unit-Test-Tool-Suite diesen Test viel nützlicher machen.

S.Lott
quelle
8
Ich mag Ihre erste Aussage, nur die relevanten Dinge zu testen. In Bezug auf die Effizienz von manuellen Tests im Vergleich zu Komponententests glaube ich nicht, dass meine Aussage vollständig falsch ist, und auch nicht, dass Ihre Aussage vollständig wahr ist. Es scheint, dass ein Gleichgewicht zwischen automatischer und manueller Prüfung gefunden werden muss, um maximale Effizienz zu erzielen.
Ken Pespisa
9
@ Ken Pespisa: Entschuldigung. Ich habe das TDD Kool-Aid vor ungefähr zwei Jahren (nach 30 Jahren Test-Last) getrunken. Jetzt stecke ich beim ersten Test fest. Es hat mich sehr viel produktiver gemacht, weil ich beim Bauen weniger nachzudenken habe.
S.Lott
3
@ Ken Pespisa: Nein. Die Antworten sind ausgewogen. Wenn Sie gefragt werden, ob es richtig ist, durch Null zu dividieren, erhalten Sie überwältigende Antworten, die sich aus einem bestimmten Grund in eine Richtung neigen. Wenn Sie gefragt werden, ob es sqrt(-1)sich um eine Ganzzahl handeln soll, erhalten Sie überwältigende Rückmeldungen. Das Gleichgewicht liegt bei "wie" und "welcher Reihenfolge". Die bloße Tatsache ist, dass Sie testen müssen . Schreiben Sie also zuerst die Tests und stellen Sie sicher, dass sie funktionieren.
S.Lott
21
Betrachten Sie Unit-Tests der Schnittstelle und nicht der Implementierungsdetails. Testen Sie die Grenzwerte und Grenzfälle. Testen Sie den riskanten Code. Viele Codes sind einfach genug, um durch Überprüfung überprüft zu werden, obwohl die Überprüfung Ihres Codes fehleranfälliger ist als die Überprüfung des Codes eines anderen. Die erstmaligen manuellen Tests sind möglicherweise effizienter, zum zehnten Mal sind automatisierte Tests weit voraus.
BillThor
10
"Der Code ist erst fertig, wenn die Tests bestanden sind" - Nicht wirklich, IMO. Code startet, wenn er die Tests besteht. Code wird erst nach ein oder zwei Jahren Laufzeit erstellt und Stresstests und Integrationstests mit einer großen, aktiven und ungeduldigen Anwenderbasis unterzogen. Das ist die einzige Prüfung, die wirklich zählt.
Vector
107

Stellen Sie sich vor, Sie hätten eine Reihe von Tests, die in einem Eyeblink ausgeführt werden könnten und ein grünes oder rotes Licht aufleuchten lassen. Stellen Sie sich vor, diese Testsuite hat alles getestet ! Stellen Sie sich vor, Sie müssten nur ^ T eingeben, um die Testsuite auszuführen. Welche Macht würde dir das geben?

Könnten Sie den Code ändern, ohne Angst zu haben, etwas zu beschädigen? Können Sie ein neues Feature hinzufügen, ohne befürchten zu müssen, ein altes Feature zu beschädigen? Können Sie unordentlichen Code schnell bereinigen, ohne befürchten zu müssen, Schaden anzurichten?

Ja, du könntest all diese Dinge tun! Und was würde mit Ihrem Code im Laufe der Zeit passieren? Es würde sauberer und sauberer werden, da es kein Risiko geben würde, es zu reinigen.

Stellen wir uns vor, Sie hätten eine kleine Fee auf der Schulter. Jedes Mal, wenn Sie eine Codezeile geschrieben haben, fügte die Fee der Testsuite etwas hinzu, das prüfte, ob diese Codezeile das tat, was sie tun sollte. So konnten Sie alle paar Sekunden ^ T drücken und sehen, dass die letzte Codezeile, die Sie geschrieben haben, funktioniert hat.

Wie viel Debugging würdest du tun?

Wenn das nach Fantasie klingt, haben Sie recht. Aber die Realität sieht nicht viel anders aus. Ersetzen Sie den Eyeblink durch ein paar Sekunden und die Fee durch die TDD-Disziplin, und Sie haben es so ziemlich geschafft.

Angenommen, Sie kehren zu einem System zurück, das Sie vor einem Jahr erstellt haben, und Sie haben vergessen, eines der zentralen Objekte zu erstellen. Es gibt Tests, die das Objekt so erstellen, wie es erstellt werden kann. Sie können diese Tests lesen und Ihr Gedächtnis auf Trab halten. Müssen Sie eine API aufrufen? Es gibt Tests, die diese API so aufrufen, wie sie aufgerufen werden kann. Diese Tests sind kleine Dokumente , die in einer Sprache verfasst sind , die Sie verstehen. Sie sind völlig eindeutig. Sie sind so förmlich, dass sie ausgeführt werden. Und sie können nicht mit der Anwendung synchronisiert werden!

Lohnt sich die Investition nicht? Du willst mich wohl veralbern! Wie konnte jemand diese Testreihe NICHT wollen? Tu dir selbst einen Gefallen und hör auf, über Albernheit zu streiten. Erfahren Sie, wie Sie TDD gut beherrschen und wie viel schneller Sie arbeiten und wie viel sauberer Ihr Code ist.

Onkel Bob.
quelle
28
Wow, der Onkel Bob? Es ist toll, hier deine Gedanken zu sammeln. Ich stimme Ihnen in Bezug auf die Vorteile von TDD zu, da ist wirklich kein Argument zu haben. Die Frage ist über die Investition von Zeit und den ROI. Es ist nicht albern für mich, über diese Dinge nachzudenken. Angenommen, für ein Projekt benötige ich 50% mehr Zeit, um TDD abzuschließen, als für ein Projekt ohne TDD, und die Fee gibt an, dass ich nur 10% Zeit im Vergleich zu manuellen Tests während der gesamten Laufzeit des Projekts einsparen kann. Das mag wie eine Fantasie erscheinen, aber ich halte es bei bestimmten Projekten für durchaus plausibel.
Ken Pespisa
11
@Ken "Stellen Sie sich vor, ein Projekt dauert mit TDD 50% länger als ohne". Das klingt für mich EXAKT nach Fantasie. Tatsächlich hört es sich so an, als hätten Sie diese Figur vor Ort erfunden, ohne eine Spur von Beweisen, die sie stützen könnten.
Rein Henrichs
18
@ Rein Henrichs - Natürlich habe ich die Nummer erfunden, es war eine hypothetische Aussage. Ich mache darauf aufmerksam, dass TDD einem Projekt eine erhebliche Menge an Zeit hinzufügt, und ich muss überlegen, ob ich im Gegenzug etwas Gleichwertiges oder Besseres bekomme. Sie müssen mich nicht von den Werten von TDD überzeugen, davon bin ich überzeugt. Aber es ist kein Allheilmittel.
Ken Pespisa
11
@Rein, was genau ist der "verfügbare Beweis"? Bitte erläutern Sie.
Ken Pespisa
22
@ Onkel Bob "Ersetze den Augenlink mit ein paar Sekunden": Du machst natürlich Witze. TDD ist ein gutes Werkzeug, aber Sie müssen nur die relevanten Teile testen, da Sie sonst mehr Zeit für die Wartung der Tests aufwenden als für ernsthafte Entwicklungen. Dies gilt insbesondere dann, wenn sich die Anforderungen sehr schnell ändern: Sie schreiben ständig Tests für Klassen, die sich ständig ändern, und werfen sie weg. Ich sage nicht, dass TDD schlecht ist, es muss nur sinnvoll verwendet und nicht mechanisch angewendet werden, wie Sie vermuten.
Giorgio
34

Der Fehler, den Sie machen, besteht darin, dass Sie das Testen als Zeitinvestition ohne unmittelbare Rendite ansehen. Das muss nicht so funktionieren.

Das Schreiben von Tests konzentriert Sie zunächst wirklich darauf, was dieser Teil Ihres Codes zu tun hat.

Wenn Sie sie zweitens ausführen, werden Fehler aufgedeckt, die andernfalls beim Testen auftreten würden.

Drittens zeigt das Ausführen manchmal Fehler, die sonst beim Testen nicht aufgetaucht wären, und beißen Sie dann in der Produktion wirklich in den Arsch.

Viertens: Wenn Sie einen Fehler mit einem laufenden System feststellen und einen Komponententest für diesen Fehler erstellen, können Sie diesen Fehler später nicht erneut einführen. Das kann eine große Hilfe sein. Wiedereintretende Fehler sind häufig und sehr ärgerlich.

Fünftens: Wenn Sie jemals Code an eine andere Person übergeben müssen, erleichtert eine Testsuite deren Leben erheblich. Auch wenn Sie ein Projekt ignoriert haben und nach ein paar Jahren wieder darauf zurückkommen, werden Sie nicht mehr so ​​nah dran sein und es wird auch für Sie hilfreich sein.

Ich habe durchweg die Erfahrung gemacht, dass bei der Entwicklung eines Projekts durch ordnungsgemäße Komponententests der Prozess immer schneller und zuverlässiger wurde.

Glenatron
quelle
2
@Ken, Testsuiten sind Spezifikationen in ausführbarer Form.
32

Die Jungs von JUnit (Java Unit Test Framework) haben die Philosophie, dass wenn es zu einfach ist zu testen, testen Sie es nicht . Ich empfehle dringend, die häufig gestellten Fragen zu Best Practices zu lesen , da sie ziemlich pragmatisch sind.

TDD ist ein anderer Prozess zum Schreiben Ihrer Software. Die Grundvoraussetzung für Unit-Tests ist, dass Sie weniger Zeit für den Debugger aufwenden müssen, um den Code durchzuarbeiten, und schneller herausfinden, ob Ihre Codeänderung versehentlich etwas anderes im System zerstört. Das passt zu TDD. Der TDD-Zyklus sieht folgendermaßen aus:

  1. Schreibe einen Test
  2. Schau zu, wie es versagt (beweise, dass du etwas zu tun hast)
  3. Schreiben Sie genau das auf, was für den Test erforderlich ist - nicht mehr.
  4. Pass auf, wie es vergeht (yay!)
  5. Refactor (besser machen)
  6. Waschen, ausspülen und wiederholen

Was bei der Anwendung von TDD weniger offensichtlich ist, ist, dass es die Art und Weise ändert, in der Sie Code schreiben . Indem Sie sich zwingen, darüber nachzudenken, wie Sie die Funktionsfähigkeit des Codes testen / validieren, schreiben Sie testbaren Code. Und da es sich um Unit-Tests handelt, bedeutet dies normalerweise, dass Ihr Code modularer wird. Modularer und testbarer Code ist für mich von vornherein ein großer Gewinn.

Müssen Sie jetzt Dinge wie C # -Eigenschaften testen? Stellen Sie sich eine Eigenschaft vor, die wie folgt definiert ist:

bool IsWorthTesting {get; set;}

Die Antwort wäre "nein", es lohnt sich nicht zu testen, da Sie zu diesem Zeitpunkt die Sprachfunktion testen. Vertrauen Sie einfach darauf, dass die C # -Plattform-Leute es richtig verstanden haben. Außerdem, wenn es fehlschlug, was könnten Sie tun, um es zu beheben?

Außerdem werden Sie feststellen, dass bestimmte Teile Ihres Codes zu aufwendig sind, um sie ordnungsgemäß zu testen. Das heißt, tun Sie es nicht, sondern stellen Sie sicher, dass Sie den Code testen, der für das heikle Problem verwendet wird:

  • Überprüfte Ausnahmen, die nur bei einer fehlerhaften Installation auftreten können. Java hat eine Menge davon. Sie müssen einen catch-Block schreiben oder die aktivierte Ausnahme deklarieren, auch wenn dies auf keinen Fall fehlschlagen kann, ohne die installierten Dateien zu hacken.
  • Benutzeroberflächen. Das Auffinden des zu testenden Steuerelements und das Aufrufen der richtigen Ereignisse zum Simulieren der Aktionen eines Benutzers sind sehr mühsam und in einigen Fällen unmöglich. Wenn Sie jedoch das Model / View / Controller-Muster verwenden, können Sie sicherstellen, dass Ihr Modell und die Controller getestet wurden, und den View-Teil dem manuellen Testen überlassen.
  • Client / Server-Interaktionen. Dies ist kein Komponententest mehr, sondern ein Integrationstest . Schreiben Sie alle Teile, die zum Senden und Empfangen von Nachrichten über das Kabel erforderlich sind, aber nicht über das Kabel. Ein guter Ansatz besteht darin, die Verantwortung des Codes zu reduzieren, der tatsächlich über die Leitung mit der Rohkommunikation kommuniziert. Verspotten Sie in Ihrem Unit-Test-Code das Kommunikationsobjekt, um sicherzustellen, dass sich die Dienste wie erwartet verhalten.

Ob Sie es glauben oder nicht, TDD wird Ihnen helfen, in ein nachhaltiges Entwicklungstempo zu geraten. Das liegt nicht an der Magie, sondern daran, dass Sie eine enge Rückkopplungsschleife haben und wirklich dumme Fehler schnell erkennen können. Die Kosten für die Behebung dieser Fehler sind im Wesentlichen konstant (zumindest für Planungszwecke ausreichend), da die kleinen Fehler niemals zu großen Fehlern werden. Vergleichen Sie das mit der Burstigkeit von Code-Binge- / Debug-Purge-Sprints.

Berin Loritsch
quelle
24

Sie müssen die Kosten für das Testen mit den Kosten für Fehler in Einklang bringen.

Das Schreiben eines 10-Zeilen-Unit-Tests für eine Funktion, die eine Datei öffnet, bei der der Fehler "Datei nicht gefunden" lautet, ist sinnlos.

Eine Funktion, die etwas Komplexes mit einer komplexen Datenstruktur macht - dann natürlich ja.

Das Knifflige liegt dazwischen. Denken Sie jedoch daran, dass der wahre Wert von Komponententests nicht die jeweilige Funktion testet, sondern die kniffligen Wechselwirkungen zwischen ihnen. Ein Komponententest, der feststellt, dass eine Änderung an einem Codebit eine Funktion in einem anderen Modul in 1000 Zeilen Entfernung unterbricht, ist das Gewicht des Kaffees wert.

Martin Beckett
quelle
23

Testen ist Glücksspiel.

Das Erstellen eines Tests ist eine Wette, dass die Kosten für Fehler in einer Einheit, die bei diesem Test (jetzt und bei allen zukünftigen Code-Revisionen) auftreten und nicht abgefangen werden, höher sind als die Kosten für die Entwicklung des Tests. Zu diesen Kosten für die Testentwicklung zählen Dinge wie Gehaltsabrechnung für zusätzliche Testentwicklung, zusätzliche Markteinführungszeit, entgangene Opportunitätskosten durch das Nichtcodieren anderer Dinge usw.

Wie bei jeder Wette gewinnt man manchmal, manchmal verliert man.

Manchmal setzt sich späte Software mit weitaus weniger Fehlern gegen schnelles, aber fehlerhaftes Material durch, das zuerst auf den Markt kommt. Manchmal das Gegenteil. Sie müssen sich die Statistiken in Ihrem speziellen Bereich ansehen und wie viel Management spielen möchte.

Bei einigen Arten von Fehlern ist es möglicherweise so unwahrscheinlich, dass sie gemacht werden oder dass sie sich aus frühen Hygienetests ergeben, dass sich statistisch gesehen die Zeit nicht lohnt, zusätzliche spezifische Tests zu erstellen. Aber manchmal sind die Kosten eines Fehlers so hoch (medizinisch, nuklear usw.), dass ein Unternehmen eine Verlustwette abschließen muss (ähnlich wie beim Abschluss einer Versicherung). Viele Apps haben nicht so hohe Ausfallkosten und benötigen daher keinen höheren unwirtschaftlichen Versicherungsschutz. Andere tun es.

hotpaw2
quelle
3
Gute Antwort. Eine der wenigen, die meine ursprüngliche Frage wirklich beantwortet. Ich habe mich in die Welt des Testens vertieft, seit ich diesen Beitrag geschrieben habe (übrigens mag ich ihn). Ich muss ihn besser verstehen, bevor ich wirklich weiß, wann ich ihn verwenden soll (oder nicht). Aus vielen hier genannten Gründen würde ich es vorziehen, es die ganze Zeit zu verwenden. Aber letztendlich kommt es darauf an, wie viel schneller ich darauf komme, denn am Ende ist es ein Spiel meiner Zeit, das von meinem Unternehmen / Kunden kontrolliert wird, und oft konzentrieren sie sich auf die unteren Ecken des Projektdreiecks: en. wikipedia.org/wiki/Project_triangle
Ken Pespisa
10

Mein Rat ist, nur den Code zu testen, den Sie richtig arbeiten möchten.

Testen Sie nicht den Code, der fehlerhaft sein soll, und verursachen Sie später Probleme.

Nick Hodges
quelle
9
Erinnert mich an das Sprichwort meines Zahnarztes: Sie müssen nicht alle Zähne putzen, nur die, die Sie behalten möchten.
Ken Pespisa
Ich gestehe, das hat mich dazu gebracht, darüber nachzudenken. ;-)
Nick Hodges
8

Ich frage mich oft, ob ich einen TDD-Ansatz ausprobieren soll. Es klingt nach einer guten Idee, aber ich kann die zusätzliche Arbeit ehrlich gesagt nie rechtfertigen.

TDD und Unit Testing sind nicht dasselbe.

Sie können Code schreiben und später Unit-Tests hinzufügen. Das ist kein TDD und eine Menge zusätzlicher Arbeit.

TDD ist die Praxis des Codierens in einer Rotlichtschleife. Grünes Licht. Refactor-Iterationen.

Dies bedeutet, dass Sie Tests für Code schreiben, der noch nicht vorhanden ist, die fehlgeschlagenen Tests beobachten, den Code korrigieren, damit die Tests funktionieren, und dann den Code "richtig" machen. Das erspart Ihnen oft Arbeit

Einer der Vorteile von TDD besteht darin, dass weniger über Wissenswertes nachgedacht werden muss. Dinge wie Off-by-One-Fehler verschwinden. Sie müssen die API-Dokumentation nicht durchsuchen, um herauszufinden, ob die zurückgegebene Liste bei 0 oder 1 beginnt.

Paul Butcher
quelle
Könnten Sie näher erläutern, wie einzelne Fehler verschwinden? Wollen Sie damit sagen, dass Sie Ihre Antwort darauf, ob der Index eines Arrays null- oder einsbasiert ist, schneller durch Testen erhalten können als durch Durchsuchen der Dokumentation? Scheint mir unwahrscheinlich - ich bin ziemlich schnell auf Google :)
Ken Pespisa
1
Tatsächlich ist das Schreiben von TDD eine hervorragende Möglichkeit, eine API zu untersuchen (einschließlich einer älteren Codebasis, um Funktionen zu dokumentieren).
Frank Shearar
Es ist auch sehr nützlich, wenn sich die API ändert ... Sie haben plötzlich einige
fehlerhafte
@ Ken Pespisa, es ist definitiv schneller - schreibe den Code basierend darauf, ob du denkst, dass es 0 oder 1 ist, führe ihn aus und repariere ihn, wenn nötig. Die meiste Zeit haben Sie Recht und Sie hätten übersprungen, es nachzuschlagen. Wenn Sie sich irren, wissen Sie es innerhalb von 10 Sekunden.
Paul Butcher
Sehr interessanter Vorteil. Ich mag das irgendwie.
Ken Pespisa
3

Ich habe an einem System gearbeitet, in dem wir fast alles getestet haben. Die bemerkenswerten Ausführungen zum Testen waren der PDF- und XLS-Ausgabecode.

Warum? Wir konnten die Teile testen, die die Daten gesammelt und das Modell erstellt haben, mit dem die Ausgabe erstellt wurde. Wir konnten auch die Teile testen, die herausfanden, welche Teile des Modells in die PDF-Dateien passen würden. Wir konnten nicht testen, ob die PDF-Datei in Ordnung war, da dies völlig subjektiv war. Wir konnten nicht testen, ob alle Teile eines PDF-Dokuments für einen typischen Benutzer lesbar sind, da dies auch subjektiv war. Oder ob die Wahl zwischen Balken- und Kreisdiagrammen für den Datensatz richtig war.

Wenn die Ausgabe subjektiv sein soll, gibt es nur wenige Unit-Tests, die Sie durchführen können, was die Mühe wert ist.

sal
quelle
Tatsächlich handelt es sich bei dieser Art von Tests wahrscheinlich um "Integrationstests". Und ja, Integrationstests sind viel schwieriger als Unit-Tests, und ein Grund dafür ist, dass die Regeln für das, was "richtig" ist, manchmal sehr kompliziert oder sogar subjektiv sind.
sleske
2

In vielen Fällen dauert ein "Schreiben-Dann-Manuell-Test" nicht länger als ein paar Tests zu schreiben. Die Zeitersparnis ergibt sich aus der Möglichkeit, diese Tests jederzeit erneut durchzuführen.

Denken Sie daran: Wenn Sie bei Ihren Tests eine angemessene Funktionsabdeckung haben (nicht zu verwechseln mit der Codeabdeckung) und Sie beispielsweise 10 Funktionen haben - wenn Sie auf eine Schaltfläche klicken, haben Sie ungefähr 10 Jahre Zeit , Ihre Tests erneut durchzuführen ... während Sie sich zurücklehnen und Ihren Kaffee trinken.

Sie auch nicht haben , um die minutae zu testen. Sie können Integrationstests schreiben, die Ihre Funktionen abdecken, wenn Sie nicht auf die kleinsten Details eingehen möchten ... IMO, einige Komponententests sind zu detailliert, um Sprache und Plattform und nicht den Code zu testen.

TL; DR Es ist wirklich nie angebracht, weil die Vorteile einfach zu gut sind.

Steven Evers
quelle
2

Zwei sehr gute Antworten, auf die ich gestoßen bin, sind hier:

  1. Wann ist ein Komponententest oder ein manueller Test durchzuführen?
  2. Was Sie beim Unit Testing nicht testen sollten

Die Gründe für die Vermeidung von wahrgenommenem Overhead:

  • Sofortige Zeit- / Kostenersparnis für Ihr Unternehmen
  • Potenzielle Zeit- / Kostenersparnis bei der Fehlerbehebung / Wartbarkeit / Erweiterung auf lange Sicht, auch wenn Sie weg sind.

Möchten Sie nicht ein großartiges Produkt als Beweis für die Qualität Ihrer Arbeit hinterlassen? Sprichst du egoistisch, ist es nicht besser für dich, dass du es tust?

Aditya P
quelle
1
Gute Frage zum Schluss. Ich bin absolut stolz auf meine Arbeit und meine Bewerbungen funktionieren sehr gut (wenn ich so mutig bin). Aber Sie haben Recht - mit der Unterstützung einiger Tests könnten sie sogar noch besser sein. Ich denke, ich möchte versuchen, so viele nützliche Tests wie möglich in der Zeit zu integrieren, in der ich an dem Projekt arbeiten muss, ohne von der Codeabdeckung zu besessen zu sein.
Ken Pespisa
1

Professionelle Entwickler schreiben Komponententests, weil sie längerfristig Zeit sparen. Sie werden Ihren Code früher oder später testen, und wenn Sie dies nicht tun, und wenn Sie später Fehler beheben müssen, werden sie schwerer zu beheben sein und mehr Auswirkungen haben.

Wenn Sie Code ohne Tests schreiben und keine Bugs haben, ist das in Ordnung. Ich glaube nicht, dass Sie ein nicht-triviales System mit null Fehlern schreiben können, also gehe ich davon aus, dass Sie es auf die eine oder andere Weise testen.

Unit-Tests sind auch wichtig, um Regressionen beim Ändern oder Umgestalten von älterem Code zu vermeiden. Sie beweisen nicht, dass Ihre Änderung nicht den alten Code gebrochen hat, aber sie geben Ihnen viel Selbstvertrauen (solange sie natürlich bestehen :))

Ich würde nicht zurückgehen und eine ganze Reihe von Tests für Code schreiben, den Sie bereits ausgeliefert haben, aber wenn Sie das nächste Mal eine Funktion ändern müssen, würde ich vorschlagen, dass Sie versuchen, Tests für dieses Modul oder diese Klasse zu schreiben, erreichen Sie eine Abdeckung von bis zu 70%. +, bevor Sie Änderungen vornehmen. Sehen Sie, ob es Ihnen hilft.

Wenn Sie es versuchen und ehrlich sagen können, dass es keine Hilfe war, dann ist es fair genug, aber ich denke, es gibt genügend Indus- triebeweise, die dazu beitragen, dass es sich zumindest lohnt, den Ansatz zu testen.

Steve
quelle
Ich mag die Gedanken, Regressionen zu verhindern und Vertrauen zu schaffen. Das sind genau die Gründe, warum ich Tests hinzufügen möchte.
Ken Pespisa
1

Die meisten Antworten scheinen pro-TDD zu sein, obwohl die Frage nicht nach TDD, sondern nach Unit-Tests im Allgemeinen gestellt wurde.

Es gibt keine völlig objektive Regel dahinter, was der Komponententest oder nicht der Komponententest sein soll. Aber es gibt ein paar Male, bei denen es so aussieht, als würden viele Programmierer keinen Komponententest durchführen:

  1. Private Methoden

Abhängig von Ihrer OOP-Philosophie können Sie private Methoden erstellen, um komplexe Routinen von Ihren öffentlichen Methoden zu entkoppeln. Öffentliche Methoden sollen normalerweise an vielen verschiedenen Stellen aufgerufen und häufig verwendet werden, und die privaten Methoden werden nur von einer oder zwei öffentlichen Methoden in einer Klasse oder einem Modul wirklich aufgerufen, um etwas sehr Bestimmtes zu erreichen. In der Regel ist es ausreichend, Komponententests für öffentliche Methoden zu schreiben, nicht jedoch für die zugrunde liegenden privaten Methoden, die einen Teil der Magie auslösen. Wenn bei einer privaten Methode etwas schief geht, sollten Ihre Unit-Tests für öffentliche Methoden gut genug sein, um diese Probleme zu erkennen.

  1. Dinge, von denen Sie bereits wissen, dass sie funktionieren sollten (oder Dinge, die von jemand anderem getestet wurden)

Viele neue Programmierer wenden sich dagegen, wenn sie das Testen zum ersten Mal lernen, und denken, dass sie jede einzelne ausgeführte Zeile testen müssen. Wenn Sie eine externe Bibliothek verwenden und deren Funktionalität von den Autoren gut getestet und dokumentiert wurde, ist es normalerweise sinnlos, die spezifische Funktionalität in Komponententests zu testen. Beispielsweise könnte jemand einen Test schreiben, um sicherzustellen, dass sein ActiveRecord-Modell den korrekten Wert für ein Attribut mit einem "before_save" -Rückruf für die Datenbank beibehält, obwohl dieses Verhalten in Rails bereits gründlich getestet wurde. Die Methode (n), die der Rückruf aufruft (aber nicht das Rückrufverhalten selbst). Grundlegende Probleme mit importierten Bibliotheken sollten eher durch Akzeptanztests als durch Komponententests aufgedeckt werden.

Beides könnte zutreffen, egal ob Sie TDD machen oder nicht.

Ravenstine
quelle
0

Ken, ich und viele andere Entwickler sind im Laufe unserer Karriere mehrmals zu demselben Schluss gekommen wie Sie.

Die Wahrheit, von der ich glaube, dass Sie sie finden werden (wie viele andere auch), ist, dass die anfängliche Investition in das Schreiben von Tests für Ihre Anwendung entmutigend erscheint, aber wenn sie gut geschrieben und auf die richtigen Teile Ihres Codes ausgerichtet sind, können sie wirklich eine Menge sparen von Zeit.

Mein großes Problem waren die verfügbaren Test-Frameworks. Ich hatte nie das Gefühl, dass sie genau das sind, wonach ich gesucht habe, also habe ich einfach meine eigene, sehr einfache Lösung entwickelt. Es hat wirklich geholfen, mich auf die "dunkle Seite" der Regressionstests zu bringen. Ich werde ein grundlegendes Pseudo-Snippet von dem, was ich hier gemacht habe, teilen, und hoffentlich können Sie eine Lösung finden, die für Sie funktioniert.

public interface ITest {
    public string Name {
        get;
    }
    public string Description {
        get;
    }
    public List<ITest> SubTests {
        get;
    }
    public TestResult Execute();
}

public class TestResult {
    public bool Succesful {
        get;
        set;
    }

    public string ResultMessage {
        get;
        set;
    }

    private Dictionary<ITest, TestResult> subTestResults = new Dictionary<ITest, TestResult>();
    public Dictionary<ITest, TestResult> SubTestResults {
        get {
            return subTestResults;
        }
        set {
            subTestResults = value;
        }
    }
}

Der einzige schwierige Teil danach ist, herauszufinden, welche Granularitätsstufe Ihrer Meinung nach für jedes Projekt die beste ist.

Das Erstellen eines Adressbuchs erfordert natürlich weniger Tests als eine Unternehmenssuchmaschine, aber die Grundlagen ändern sich nicht wirklich.

Viel Glück!

Adam Carstensen
quelle
Ich denke, mit der Zeit werde ich herausfinden, welche Granularität die beste ist. Es ist gut zu hören, dass andere, die regelmäßig Tests erstellen, vernünftig vorgehen und nicht automatisch Tests für jedes erdenkliche Ergebnis schreiben. Meine erste Einführung in Tests war auf einer Ebene, auf der alles getestet werden muss. Tatsächlich scheint das gesamte Konzept von TDD diesem Mantra zu folgen.
Ken Pespisa
Ich denke, Sie könnten von der Verwendung eines Frameworks wie SubSpec (es ist BDD-inspiriert) profitieren, so dass Sie die Assert ("SubTest") -Isolation erhalten, während Sie die Kontexteinrichtung freigeben.
Johannes Rudolph