it-swarm.com.de

Sind Unit-Tests wirklich so nützlich?

Ich habe gerade meinen Abschluss in CS gemacht und habe derzeit einen Job als Junior .NET-Entwickler (C #, ASP.NET und Webformulare). Als ich noch an der Universität war, wurde das Thema Unit Testing zwar behandelt, aber ich habe die Vorteile nie wirklich gesehen. Ich verstehe, was es tun soll, nämlich festzustellen, ob ein Codeblock für die Verwendung geeignet ist oder nicht. Allerdings musste ich noch nie einen Unit-Test schreiben, noch hatte ich jemals das Bedürfnis dazu.

Wie bereits erwähnt, entwickle ich normalerweise mit ASP.NET-Webformularen und habe kürzlich darüber nachgedacht, einige Komponententests zu schreiben. Aber ich habe ein paar Fragen dazu.

Ich habe gelesen, dass Unit-Tests oft durch das Schreiben von "Mocks" stattfinden. Obwohl ich dieses Konzept verstehe, kann ich anscheinend nicht herausfinden, wie ich Mocks für Websites schreiben soll, die vollständig dynamisch sind und bei denen fast alles von Daten abhängt, die aus einer Datenbank stammen. Zum Beispiel: Ich verwende viele Repeater mit ItemDataBound-Ereignissen usw. (wiederum abhängig von Daten, die "unbekannt" sind).

Frage 1: Wird das Schreiben von Komponententests für ASP.NET-Webformulare häufig durchgeführt, und wenn ja: Wie kann das Problem der "dynamischen Umgebung" behoben werden?

Wenn ich mich entwickle, mache ich viel Versuch und Irrtum durch. Das bedeutet nicht, dass ich nicht weiß, was ich tue, aber ich meine, dass ich normalerweise Code schreibe, Hit Ctrl F5 und sehen, was passiert. Während dieser Ansatz die meiste Zeit die Arbeit erledigt, habe ich manchmal das Gefühl, ein wenig ahnungslos zu sein (aufgrund meiner geringen Erfahrung). Manchmal verschwende ich auch so viel Zeit.

Frage 2: Würden Sie mir raten, Unit-Tests zu schreiben? Ich denke, es könnte mir bei der tatsächlichen Implementierung helfen, aber andererseits habe ich das Gefühl, dass es mich verlangsamen könnte.

98
Jane Doe

Meiner Meinung nach: Ja, und ja, das solltest du.

  1. Sie geben Ihnen Vertrauen in die Änderungen, die Sie vornehmen (alles andere funktioniert noch). Dieses Vertrauen ist das, was Sie brauchen, um den Code zu formen, sonst haben Sie möglicherweise Angst, Dinge zu ändern.

  2. Sie verbessern Ihren Code. Die einfachsten Fehler werden bei den Unit-Tests frühzeitig erkannt. Das frühzeitige Erkennen und Beheben von Fehlern ist immer billiger als das spätere Beheben von Fehlern, z. B. wenn die Anwendung in Produktion ist.

  3. Sie dienen anderen Entwicklern als Dokumentation zur Funktionsweise und Verwendung Ihres Codes.

Das erste Problem, mit dem Sie konfrontiert sind, ist, dass ASP.NET an sich nicht beim Schreiben von Komponententests hilft - tatsächlich funktioniert es gegen Sie. Wenn Sie eine andere Wahl haben, verwenden Sie ASP.NET MVC , das für Unit-Tests erstellt wurde. Wenn Sie ASP.NET MVC nicht verwenden können, sollten Sie das Muster MVP in ASP.NET verwenden, damit Sie Ihre Logik zumindest problemlos testen können.

Außerdem müssen Sie nur das Schreiben von Komponententests beherrschen. Wenn Sie TDD üben, wird Ihr Code testbar erstellt - mit anderen Worten: Schön und sauber.

Ich würde Ihnen raten, das Programm zu üben und zu koppeln. Während des Lesens:

Oder für einen ersten Überblick:

124
KeesDijk

Nein.

Das Konzept hinter Unit-Tests basiert auf einer Prämisse, von der bekannt ist, dass sie falsch ist, bevor Unit-Tests jemals erfunden wurden: Die Idee, dass Tests beweisen können, dass Ihr Code korrekt ist.

Viele Tests, die alle bestehen, beweisen nur eines: Sie haben viele Tests, die alle bestanden haben. Es beweist nicht, dass das, was die Tests testen, mit der Spezifikation übereinstimmt. Es beweist nicht, dass Ihr Code frei von Fehlern ist, die Sie beim Schreiben der Tests nie berücksichtigt haben. (Und die Dinge, die Sie testen wollten, waren die möglichen Probleme, auf die Sie sich konzentriert haben, also haben Sie sie wahrscheinlich trotzdem richtig gemacht!) Und last but not least beweist es nicht, dass die Tests, die selbst Code sind, sind frei von Fehlern. (Folgen Sie dem letzten bis zu seiner logischen Schlussfolgerung und Sie erhalten Schildkröten ganz nach unten .)

Djikstra hat das Konzept verworfen von Tests als Beweis für die Richtigkeit im Jahr 1988, und was er schrieb, bleibt bis heute genauso gültig:

Es ist nun zwei Jahrzehnte her, seit darauf hingewiesen wurde, dass Programmtests das Vorhandensein von Fehlern überzeugend belegen können, aber niemals deren Fehlen. Nachdem der Softwareentwickler diese gut publizierte Bemerkung ausführlich zitiert hat, kehrt er zur Tagesordnung zurück und verfeinert seine Teststrategien weiter, genau wie der Alchemist von früher, der seine chrysokosmischen Reinigungen weiter verfeinerte.

Das andere Problem beim Testen von Einheiten besteht darin, dass eine enge Kopplung zwischen Ihrem Code und der Testsuite hergestellt wird. Wenn Sie den Code ändern, werden einige Fehler erwartet, die einige Tests beschädigen würden. Wenn Sie jedoch den Code ändern, weil sich die Anforderungen selbst geändert haben, werden viele Tests fehlgeschlagen, und Sie müssen jeden einzelnen manuell durchgehen und entscheiden, ob der Test noch gültig ist oder nicht. (Und es ist auch möglich, obwohl weniger häufig, dass ein vorhandener Test, der ungültig sein sollte, weiterhin besteht, weil Sie vergessen haben, etwas zu ändern, das geändert werden musste .)

Unit-Tests sind nur die neuesten in einer langen Reihe von Entwicklungsmodalitäten, die versprechen, das Schreiben von Arbeitscode zu vereinfachen, ohne ein guter Programmierer zu sein. Keiner von ihnen hat es jemals geschafft, sein Versprechen zu erfüllen, und dieses auch nicht. Es gibt einfach keine Abkürzung, um tatsächlich zu wissen, wie man Arbeitscode schreibt .

Es gibt einige Berichte darüber, dass automatisierte Tests in Fällen wirklich nützlich sind, in denen Stabilität und Zuverlässigkeit von größter Bedeutung sind. Zum Beispiel das SQLite-Datenbankprojekt. Aber was es braucht, um ihre Zuverlässigkeit zu erreichen ist für die meisten Projekte höchst unwirtschaftlich: ein Verhältnis von Test zu tatsächlichem SQLite-Code von fast 1200: 1. Die meisten Projekte können sich das nicht leisten und brauchen es sowieso nicht.

95
Mason Wheeler

Wenn Sie jemals den Vorteil gesehen haben, eine Hauptmethode zum Testen eines kleinen Codeteils für die Schule zu schreiben, ist Unit Testing die Professional/Enterprise-Version derselben Praxis.

Stellen Sie sich auch den Aufwand vor, den Code zu erstellen, Ihren lokalen Webserver zu starten, zu der betreffenden Seite zu navigieren, die Daten einzugeben oder die Eingabe auf den richtigen Test-Seed zu setzen, das Formular einzureichen und die Ergebnisse zu analysieren ... im Vergleich zum Erstellen und Schlagen die Schaltfläche nUnit run.

Hier ist auch ein lustiges Bild ... enter image description here

Ich habe dieses Bild hier gefunden:
http://www.howtogeek.com/102420/geeks-versus-non-geeks-when-doing-repetitive-tasks-funny-chart/

60
Heath Lilley

Unit-Tests sind heutzutage etwas mystisch. Die Leute behandeln es so, als ob eine 100% ige Testabdeckung ein heiliger Gral ist und als ob Unit-Tests der einzig wahre Weg sind, Software zu entwickeln.

Sie verpassen den Punkt.

Unit Testing ist nicht die Antwort. Testen ist.

Wann immer diese Diskussion auftaucht, wird jemand (oft sogar ich) Dijkstras Zitat heraussuchen: "Programmtests können das Vorhandensein von Fehlern nachweisen, aber niemals deren Abwesenheit." Dijkstra hat recht: Tests reichen nicht aus, um zu beweisen, dass Software wie beabsichtigt funktioniert. Aber es ist notwendig : Auf einer bestimmten Ebene muss es möglich sein, zu demonstrieren , dass Software das tut, was Sie wollen.

Viele Menschen testen von Hand. Selbst überzeugte TDD-Enthusiasten führen manuelle Tests durch, obwohl sie dies manchmal nicht zugeben. Es kann nicht geholfen werden: Kurz bevor Sie in den Konferenzraum gehen, um Ihrem Kunden/Chef/Investoren/etc. Ihre Software vorzuführen, werden Sie sie von Hand durchgehen, um sicherzustellen, dass sie funktioniert. Daran ist nichts auszusetzen, und in der Tat wäre es verrückt, einfach zu erwarten, dass alles reibungslos verläuft, ohne es manuell zu durchlaufen - das heißt, es zu testen - selbst wenn Sie es haben 100% Unit-Test-Abdeckung und größtes Vertrauen in Ihre Tests.

Manuelle Tests sind jedoch selten ausreichend , obwohl sie zum Erstellen von Software erforderlich sind . Warum? Weil manuelle Tests mühsam und zeitaufwändig sind und von Menschen durchgeführt werden. Und Menschen sind notorisch schlecht darin, mühsame und zeitaufwändige Aufgaben auszuführen: Sie vermeiden es, sie zu erledigen, wann immer dies möglich ist, und sie tun sie oft nicht gut, wenn sie dazu gezwungen werden.

Maschinen hingegen sind hervorragend für mühsame und zeitaufwändige Aufgaben geeignet. Dafür wurden schließlich Computer erfunden.

Daher ist Testen von entscheidender Bedeutung, und automatisiertes Testen ist der einzig sinnvolle Weg, um sicherzustellen, dass Ihre Tests konsistent angewendet werden. Bei der Entwicklung der Software ist es wichtig, diese zu testen und erneut zu testen. Eine andere Antwort hier weist auf die Bedeutung von Regressionstests hin. Aufgrund der Komplexität von Softwaresystemen verursachen häufig scheinbar harmlose Änderungen an einem Teil des Systems unbeabsichtigte Änderungen (d. H. Fehler) in anderen Teilen des Systems. Sie können diese unbeabsichtigten Änderungen nicht ohne irgendeine Form von Tests entdecken. Und wenn Sie zuverlässige Daten zu Ihren Tests haben möchten, müssen Sie Ihre Tests systematisch durchführen, was bedeutet, dass Sie über eine Art automatisiertes Testsystem verfügen müssen.

Was hat das alles mit Unit-Tests zu tun? Aufgrund ihrer Natur werden Unit-Tests von der Maschine und nicht von einem Menschen durchgeführt. Daher haben viele Menschen den falschen Eindruck, dass automatisierte Tests gleich Unit-Tests sind. Das stimmt aber nicht: Unit-Tests sind nur extra kleine automatisierte Tests.

Was ist nun der Wert in extra kleinen automatisierten Tests? Der Vorteil ist, dass sie Komponenten eines Softwaresystems in Isolation testen, was eine genauere Ausrichtung des Testens ermöglicht, und hilft beim Debuggen . Unit-Tests bedeuten jedoch nicht unbedingt Tests mit höherer Qualität . Dies führt häufig zu Tests mit höherer Qualität, da Software detaillierter behandelt wird. Es ist jedoch möglich, das Verhalten nur eines vollständigen Systems und nicht seiner Verbundteile vollständig zu testen und es dennoch gründlich zu testen.

Aber selbst bei einer 100% igen Testabdeckung kann ein System möglicherweise nicht gründlich getestet werden. Weil einzelne Komponenten möglicherweise perfekt isoliert arbeiten und dennoch zusammen scheitern. Daher ist das Testen von Einheiten zwar sehr nützlich, aber nicht ausreichend , um sicherzustellen, dass die Software wie erwartet funktioniert. In der Tat ergänzen viele Entwickler Komponententests durch automatisierte Integrationstests, automatisierte Funktionstests und manuelle Tests.

Wenn Sie in Komponententests keinen Wert sehen, können Sie am besten mit einer anderen Art von automatisiertem Test beginnen. In einer Webumgebung bietet die Verwendung eines Browser-Automatisierungstest-Tools wie Selenium häufig einen großen Gewinn für eine relativ kleine Investition. Sobald Sie Ihre Zehen ins Wasser getaucht haben, können Sie leichter erkennen, wie hilfreich automatisierte Tests sind. Sobald Sie automatisierte Tests durchgeführt haben, sind Unit-Tests viel sinnvoller, da sie eine schnellere Abwicklung ermöglichen als große Integrations- oder End-to-End-Tests, da Sie Tests nur auf die Komponente ausrichten können, an der Sie gerade arbeiten.

TL; DR: Mach dir noch keine Sorgen über Unit-Tests . Sorgen Sie sich zuerst darum, Ihre Software zu testen .

49
Daniel Pryden

es kommt darauf an

Dies ist eine Antwort, die Sie bei der Softwareentwicklung häufig sehen werden, aber der Nutzen von Komponententests hängt wirklich davon ab, wie gut sie geschrieben sind. Eine nominelle Anzahl von Komponententests, die die Funktionalität der Anwendung für Regressionstests überprüfen, kann sehr nützlich sein. Eine Vielzahl einfacher Tests, die die Rückgabe von Funktionen überprüfen, können jedoch völlig nutzlos sein und ein falsches Sicherheitsgefühl vermitteln, da die Anwendung "viele Komponententests" aufweist.

Darüber hinaus ist Ihre Zeit als Entwickler wertvoll und die Zeit, die Sie für das Schreiben von Komponententests aufgewendet haben, ist die Zeit, die Sie nicht für das Schreiben neuer Funktionen aufgewendet haben. Auch dies bedeutet nicht, dass Sie keine Komponententests schreiben sollten, aber benötigt jede einzelne öffentliche Funktion einen Komponententest? Ich würde sagen, dass die Antwort nein ist. Muss der Code, der die Validierung von Benutzereingaben durchführt, einem Komponententest unterzogen werden? Sehr wahrscheinlich, da dies ein häufiger Fehlerpunkt in Anwendungen ist.

Dies ist einer der Bereiche, in denen Erfahrung ins Spiel kommt. Mit der Zeit werden Sie die Teile der Anwendung erkennen, die von einem Komponententest profitieren könnten. Es wird jedoch eine Weile dauern, bis Sie diesen Punkt erreichen.

41
rjzii

Projekte, die für Universitätsklassen durchgeführt werden, unterscheiden sich erheblich von Geschäftsanwendungen, die Sie bei Ihrer Arbeit schreiben. Der Unterschied ist die Lebensdauer. Wie lange "lebt" das Universitätsprojekt? In den meisten Fällen beginnt es, wenn Sie die erste Codezeile schreiben, und endet, wenn Sie Ihre Note erhalten. Man könnte sagen, dass es effektiv nur für die Zeit der Implementierung lebt. "Release" ist normalerweise gleich "Death".

Für Unternehmen erstellte Software übertrifft den Release-Death-Punkt des Universitätsprojekts und lebt so lange weiter, wie es das Unternehmen benötigt. Welches ist sehr lang . Wenn es um Geld geht, wird niemand einen kaputten Cent ausgeben, um "cooleren und ordentlicheren Code" zu haben. Wenn Software, die vor 25 Jahren in C geschrieben wurde, immer noch funktioniert und gut genug ist (wie von den Anforderungen des Geschäftsinhabers verstanden), müssen Sie damit rechnen, sie zu warten (neue Funktionen hinzufügen, alte verbessern - Quellcode ändern).

Wir kommen zu einem sehr wichtigen Punkt - Regression . An dem Ort, an dem ich arbeite, haben wir zwei Teams, die zwei Apps warten. Eine, die vor ungefähr 5-6 Jahren mit sehr geringer Abdeckung durch Codetests * geschrieben wurde, und die zweite, neuere Version der ersten Anwendung mit ausgewachsen Testsuite (Einheit, Integration und was nicht ). Beide Teams haben spezielle manuelle (menschliche) Tester. Möchten Sie wissen, wie lange es dauert, eine neue, ziemlich grundlegende Funktion für das erste Team einzuführen? 3 bis 4 Wochen. Die Hälfte dieser Zeit ist "zu prüfen, ob alles andere noch funktioniert". Dies ist eine geschäftige Zeit für manuelle Tester. Telefone klingeln, die Leute sind verärgert, etwas ist wieder kaputt. Das zweite Team kümmert sich normalerweise in weniger als 3 Tagen um solche Probleme.

Ich sage keineswegs, dass Unit-Tests Ihren Code fehleranfällig, korrekt oder andere ausgefallene Wörter machen, die Sie sich einfallen lassen können. Weder lassen sie Käfer auf magische Weise verschwinden. In Kombination mit anderen Methoden des automatisierten Softwaretests sind Ihre Anwendungen jedoch viel wartbarer als sonst. Dies ist ein großer Gewinn.

Und zu guter Letzt ein Kommentar von Brian, der meiner Meinung nach das ganze Problem betrifft:

(...) Sie erhöhen Ihr Vertrauen (oder sollten ...), dass der Code das tut, wofür Sie ihn entworfen haben, und morgen weiter macht, was er heute tut.

Denn zwischen heute und morgen kann jemand winzige Änderungen vornehmen, die dazu führen, dass der Code des Berichtsgenerators ach so wichtig abstürzt. Tests Schieben Sie die Wahrscheinlichkeit, dass Sie dies herausfinden, bevor Ihr Kunde ein wenig an Ihre Seite tritt.

* Sie führen langsam immer mehr Tests in ihre Codebasis ein, aber wir alle wissen, wie dieses Zeug normalerweise aussieht.

38
k.m

wird das Schreiben von Komponententests für ASP.NET-Webformulare häufig durchgeführt, und wenn ja, wie kann ich das Problem der "dynamischen Umgebung" beheben?

Es wird nicht oft gemacht. Das Arbeiten mit UI-Elementen ist nicht das, was Unit-Tests können, da es keine gute Möglichkeit gibt, programmgesteuert zu überprüfen, ob die richtigen Dinge an den richtigen Stellen auf dem Bildschirm landen.

Würdet ihr mir raten, Unit-Tests zu schreiben? Ich denke, es könnte mir bei der tatsächlichen Implementierung helfen, aber andererseits habe ich das Gefühl, dass es mich verlangsamen könnte.

Wo zutreffend, ja. Sie können sehr hilfreich sein, um bestimmte Fälle auf wiederholbare Weise zu überprüfen. Sie wirken als „Reibung“ gegen störende Änderungen und als ausfallsicher, wenn Sie bessere Änderungen vornehmen.

Eine Sache zu beachten ist, dass sie werden Sie normalerweise verlangsamen.

Das ist okay.

Wenn Sie jetzt ein wenig Zeit verbringen, sparen Sie (wenn dies gut gemacht wird) in Zukunft Zeit, da sie einige Fehler erkennen, das Wiederauftreten einiger Fehler verhindern und es Ihnen etwas bequemer machen, andere Verbesserungen am Code vorzunehmen, um zu verhindern, dass er verfault.

25
Telastyn

Ich habe gerade meinen Abschluss in CS gemacht und habe derzeit einen Job als Junior .NET-Entwickler (in C # und normalerweise in ASP.NET, Webformularen - nicht in ASP.NET MVC). Als ich noch an der Universität war, wurde das Thema Unit Testing zwar behandelt, aber ich habe die Vorteile nie wirklich gesehen.

Das liegt daran, dass Sie nie groß programmiert haben.

Ich verstehe, was es tun soll - bestimmen, ob ein Codeblock geeignet ist oder nicht -, aber ich musste noch nie einen Komponententest schreiben. (noch> hatte ich jemals das Bedürfnis zu ..)

Das Schreiben von Komponententests zwingt Ihren Code dazu, sich an eine bestimmte mentale Struktur anzupassen, die testbar, gut dokumentiert und zuverlässig ist. Es ist viel mehr als das, was Sie behaupten.

-Ich habe gelesen, dass Unit-Tests oft durch das Schreiben von "Mocks" stattfinden. Obwohl ich dieses Konzept verstehe, kann ich nicht herausfinden, wie ich Mocks für Websites schreiben soll, die vollständig dynamisch sind und bei denen fast alles von Daten abhängt, die aus einer Datenbank stammen.

verspotten Sie den Datenbankzugriff mit einer Scheinklasse, die Modellklassen zurückgibt, die mit genau definierten, fest codierten Daten gefüllt sind. oder , füllen Sie eine Testdatenbank mit Fixture-Daten und arbeiten Sie von dort aus.

- Würdet ihr mir raten, Unit-Tests zu schreiben?

auf jedenfall. Lesen Sie zuerst Becks "Test Driven Development" .

Ich denke, es könnte mir bei der tatsächlichen Implementierung helfen, aber andererseits habe ich das Gefühl, dass es mich verlangsamen könnte.

Es verlangsamt dich jetzt. Aber wenn Sie stundenlang statt tagelang debuggen müssen, werden Sie Ihre Meinung ändern.

jeder Rat wird geschätzt :)

Prüfung. Vertrau mir. Leider muss es auch eine Verwaltungsrichtlinie sein, aber das spart Zeit. Tests bleiben, sie sind da, jetzt und in Zukunft. Wenn Sie die Plattform wechseln und die Tests ausführen und sie weiterhin funktionieren, wissen Sie , dass Ihre Daten wie erwartet funktionieren.

11
Stefano Borini

Bearbeiten: Ich habe mich natürlich dem TDD Pro/Contra Dogpile angeschlossen und Frage 1 übersprungen:

1 - Implementieren von Komponententests in ASP.net-Webformularen:

Wenn Sie glauben, dass Sie sie dazu bringen können, mit MVC zu arbeiten, kämpfen Sie zunächst wie ein tollwütiger Höhlenbär darum. Als Front-End-/UI-Entwickler hat mir .net MVC geholfen, .net nicht mehr zu hassen, damit ich mich besser darauf konzentrieren kann, jede Java Weblösung, auf die ich jemals gestoßen bin, zu hassen. Unit-Tests sind problematisch Da Webformulare die Grenzen zwischen Server und Client wirklich verwischen. Bei jedem Versuch, Unit-Tests durchzuführen, würde ich mich auf die Datenmanipulation konzentrieren und (hoffentlich) davon ausgehen, dass Webforms die Normalisierung von Benutzereingaben für Sie unter der Haube übernimmt.

2 - Ob sich Unit-Tests überhaupt lohnen:

In Ordnung, vollständige Offenlegung:

  • Ich bin größtenteils Autodidakt. Meine formale Ausbildung besteht darin, ein JavaScript, ein PHP und eine C # -Klasse zu mögen und mein persönliches Studium der OOP) Prinzipien und das Lesen von Dingen wie Design Patterns.

Jedoch,

  • Ich schreibe hauptsächlich für das clientseitige Web und der eigentliche Programmierteil davon ist in einer der schnellsten und lockersten Sprachen, was dynamische Typisierung, erstklassige Funktionen und Objektveränderlichkeit betrifft.

Das heißt, ich schreibe nicht für denselben Compiler oder dieselbe virtuelle Maschine. Ich schreibe für etwa 4 bis 20 verschiedene Interpretationen von drei Sprachen (ja, zwei davon sind nur deklarativ, bestimmen aber auch den grundlegenden physischen Raum der Benutzeroberfläche, mit der ich manchmal auf unterschiedliche Weise arbeite) und tun dies seit den Interpretationen a viel vielfältiger als heute. Und nein, ich bin nicht nur ein Kind, das JQuery-Zeug für Einweg-Apps einsteckt. Ich helfe dabei, ziemlich anspruchsvolle Dinge mit viel Komplexität der UI-Elemente zu erstellen und zu pflegen.

Also ja, hier und da gibt es viele Möglichkeiten für ein paar Verbesserungen, um eine massive Kaskade von Fehlern zu erzeugen, wenn Ihre Designfähigkeiten völlig beschissen sind oder Sie mittelmäßige Entwickler in großen Mengen mit 1-2 Qualitätsentwicklungsproblemen beschäftigen.

Mein Verständnis davon, was TDD für Sie tun soll, ist, dass es bei den Tests wirklich mehr darum geht, Sie zu zwingen, das Design genauer zu betrachten und sich auf die Anforderungen zu konzentrieren. Fair genug, aber das Problem hier ist, dass es untergräbt, was Sie tun sollten, nämlich eine Schnittstelle zu entwerfen, zu etwas subtilem, aber grundlegend anderem, das für Tests einer Schnittstelle entworfen wird. Der Unterschied für mich besteht darin, ein klares Bild zu zeichnen, dessen Bedeutung Mama nicht erraten muss, und die ganze Seite sehr schnell mit Grün zu füllen, damit Sie das erste Kind sein können, das seine Buntstifte auf den Tisch schlägt und "Fertig!" "" Indem Sie die Priorität auf Ergebnisse gegenüber Prozess und Design verlagern, fördern Sie im Grunde die fortgesetzte Implementierung von Müllcode, was in der Regel in erster Linie die Ursache Ihrer Probleme war.

Und dann gibt es natürlich den "nicht-der-wirklichen-Punkt" von, aber oft gelobten Nebeneffekt der Unit-Tests selbst, die Ihnen helfen, Regressionsfehler zu erkennen. TDD-Befürworter neigen dazu, sich ein wenig darüber Gedanken zu machen, ob dies tatsächlich das Ziel oder nur eine raffinierte Nebenwirkung ist, IMO, weil sie verdammt gut wissen oder zumindest vermuten, dass dies einfach nicht ausreicht, um das Fehlen von Fehlern in Ihrem Unternehmen festzustellen Code, insbesondere in einer dynamischeren Sprache wie JavaScript, in der die Annahme, dass Sie sogar jedes mögliche Szenario in einer langen Kette von Abhängigkeiten vorhersagen können, töricht ist.

In JS gibt es einen Ort für automatisierte Tests, aber eine viel bessere Nutzung Ihrer Zeit als das Anhängen eines Komponententests an jede einzelne "Einheit" Ihres Codes, die mit einer anderen in Kontakt kommt, stellt sicher, dass Sie nicht über eine Menge verfügen Müllobjekte, die Arbeit duplizieren oder deren beabsichtigte Verwendung dort in erster Linie semantisch mehrdeutig ist. Sie folgen dem Prinzip DRY. Sie abstrahieren Dinge zur Wiederverwendung/Portabilität, wenn der Wert davon offensichtlich wird (und nicht eine Minute zuvor). Sie legen konsistente Prozesse und Vorgehensweisen fest Befolgen Sie eher das Prinzip einer Zuckerbrot als eine Peitsche (dh es ist zu einfach, Ihre Sachen richtig zu verwenden, um sich die Mühe zu machen, es falsch zu machen) Anti-Patterns als Mittel zur Wiederverwendung von Code.

All dies hat mir geholfen, schwer zu diagnostizierende Fehler in meinem Code ernsthaft zu reduzieren, und Sie können darauf vertrauen, dass dies eine große Priorität für jemanden ist, der als Entwickler mit einem Browser-Set aufgetaucht ist, das Ihnen nichts Besseres zu sagen hat als " Es gibt ein Problem mit einem Objekt vom Typ 'Objekt' bei dieser imaginären Zeilennummer in einer nicht angegebenen Datei. " (gee, danke IE6) TDD würde in meiner Arbeit diese Dinge nicht fördern. Es würde den Fokus auf 100% Ergebnisse über den Prozess verlagern, bei dem es nicht wirklich darauf ankommt, was zwischen Punkt A und B liegt, solange es funktioniert. Es ist Zeitverschwendung, besser darauf zu achten, dass Ihre Daten lesbar, tragbar und leicht zu ändern sind, ohne dass es zu verwirrenden Brüchen kommt.

Oder vielleicht bin ich nur übermäßig nervös in Bezug auf das Paradigma, in dem ich verwurzelt bin, aber meiner Meinung nach ist es viel effektiver, die Zeit richtig zu machen, als Ihren Hintern zu bedecken, wenn Sie oder alle anderen auf Ihrem Team macht es falsch. Und nichts sollte Sie dazu zwingen, über Design nachzudenken, anstatt nur Dinge umzusetzen. Design sollte der verdammte Altar eines jeden Programmierers sein. Und alles, was Sie "zwingt", das Richtige zu tun oder Sie vor sich selbst zu schützen, sollte mit dem gleichen Verdacht betrachtet werden, der Flaschen Schlangenöl vorbehalten ist, IMO. Wenn Sie sich noch nicht bewusst sind, wird Schlangenöl in der modernen IT und in der allgemeinen Entwicklung in Tonnen verkauft.

8
Erik Reppen

Nach meiner Erfahrung sind Komponententests in der Tat sehr nützlich , wenn Sie mit ihnen beginnen und bei ihnen bleiben , d. H. Testgetriebene Entwicklung. Hier ist der Grund:

  • nit-Tests zwingen Sie, darüber nachzudenken, was Sie wollen und wie Sie überprüfen können, ob Sie es erhalten haben, bevor Sie den Code schreiben, der es tut. In einem TDD-Szenario schreiben Sie zuerst den Test. Sie müssen also wissen, was der Code, den Sie schreiben möchten, tun muss und wie Sie überprüfen können, ob dies erfolgreich war, um einen "roten" Test zu schreiben, den Sie dann durch Schreiben des Codes "grün" machen weitergeben. In vielen Fällen müssen Sie nur ein wenig mehr über den Algorithmus nachdenken, den Sie schreiben möchten, um diesen Test zu bestehen. Dies ist immer eine gute Sache, da er Logikfehler und "Eckfälle" reduziert. Während Sie den Test schreiben, denken Sie: "Wie könnte dies fehlschlagen" und "Was bin ich ?" hier nicht testen ", was zu einem robusteren Algorithmus führt.

  • nit-Tests zwingen Sie, darüber nachzudenken, wie der Code, den Sie schreiben möchten, verbraucht wird. Bevor ich TDD lernte, gab es VIELE Male, in denen ich Code schrieb, in dem erwartet wurde, dass eine Abhängigkeit in eine Richtung funktioniert, und dann eine Abhängigkeit erhielt, die von einem Kollegen geschrieben wurde, der auf eine völlig andere Weise funktionierte. Während dies mit TDD immer noch möglich ist, zwingt Sie der von Ihnen geschriebene Komponententest dazu, darüber nachzudenken, wie Sie das Objekt verwenden möchten, das Sie schreiben, da es sich um eine beispielhafte Verwendung dieses Objekts handelt. Sie werden das Objekt dann hoffentlich so schreiben, dass es leicht zu konsumieren und bei Bedarf anzupassen ist (obwohl die Programmierung auf vordefinierte Schnittstellen eine bessere Gesamtlösung für dieses Problem darstellt, für das kein TDD erforderlich ist).

  • nit-Tests ermöglichen es Ihnen, "durch Testen zu codieren". Ein Refactoring-Tool wie ReSharper kann Ihr bester Freund sein, wenn Sie es zulassen. Sie können es verwenden, um das Grundgerüst neuer Funktionen zu definieren, während Sie die Verwendung in einem Test definieren.

    Angenommen, Sie müssen ein neues Objekt MyClass erstellen. Sie erstellen zunächst eine Instanz von MyClass. "Aber MyClass existiert nicht!", Beschwert sich ReSharper. "Dann erstellen Sie es", sagen Sie mit Alt + Eingabetaste. Und schon haben Sie Ihre Klassendefinition. In der nächsten Zeile des Testcodes rufen Sie eine Methode MyMethod auf. "Aber das gibt es nicht!", Sagt ReSharper. "Dann erstelle es", wiederholst du mit einem weiteren Alt + Enter. Sie haben mit wenigen Tastendrücken das "Skelett" Ihres neuen Codes definiert. Während Sie die Verwendung weiter ausarbeiten, zeigt Ihnen die IDE] an, wenn etwas nicht passt, und normalerweise ist die Lösung so einfach, dass die IDE oder Ein Werkzeug, das sich anschließen lässt, weiß, wie man es repariert.

    Extremere Beispiele entsprechen dem "Triple-A" -Modell; "Arrangieren, handeln, behaupten". Richten Sie alles ein, führen Sie die eigentliche Logik aus, die Sie testen, und stellen Sie dann sicher, dass die Logik korrekt ist. Auf diese Weise zu codieren, ist sehr natürlich, die Lösung in den Test zu codieren. Mit ein paar Tastendrücken können Sie diese Logik extrahieren und an einer Stelle ablegen, an der sie im Produktionscode verwendet werden kann. Anschließend können Sie kleine Änderungen am Test vornehmen, die auf die neue Position der Logik verweisen. Wenn Sie dies auf diese Weise tun, müssen Sie den Code modular und einfach wiederverwenden, da auf die zu testenden Einheiten weiterhin zugegriffen werden muss.

  • nit-Tests laufen viele Größenordnungen schneller ab als jeder manuelle Test, den Sie sich vorstellen können. Es gibt einen Punkt, der bei größeren Projekten sehr schnell erfüllt wird und bei dem sich der Zeitaufwand für Unit-Tests zu zahlen beginnt selbst durch Reduzierung der Zeit für manuelle Tests. Sie müssen IMMER den Code ausführen, den Sie gerade geschrieben haben. Traditionell haben Sie dies manuell getan, indem Sie ein großes Programm gestartet, durch die Benutzeroberfläche navigiert, um die Situation einzurichten, für die Sie das Verhalten geändert haben, und dann die Ergebnisse erneut über die Benutzeroberfläche oder in Form von erzeugten Daten überprüft haben. Wenn der Code TDDed war, führen Sie einfach die Komponententests aus. Ich garantiere Ihnen, wenn Sie gute Komponententests schreiben, ist die letztere Option um ein Vielfaches schneller als die erstere.

  • nit-Tests fangen Regression ab. Wieder gab es viele Male, bevor ich TDD lernte, wo ich hineinging, eine chirurgische Änderung an einem Teil des Codes vornahm und bestätigte, dass die Änderung ein fehlerhaftes Verhalten in der gemeldeten Situation behebt (oder ein neues gewünschtes Verhalten hervorruft) und checkte es für die Freigabe ein, nur um festzustellen, dass die Änderung einen anderen Eckfall in einem völlig anderen Modul gebrochen hat, das denselben Codeblock wiederverwendete. In einem TDDed-Projekt kann ich einen Test schreiben, der eine Änderung überprüft, die ich vornehmen werde, die Änderung vornehmen und dann die gesamte Suite ausführen. Wenn alle anderen Verwendungen des Codes TDDed waren und meine Änderung etwas kaputt gemacht hat, die Tests für diese andere Dinge werden scheitern und ich kann nachforschen.

    Wenn Entwickler alle Codezeilen, die von einer möglichen Änderung betroffen sein könnten, manuell finden und testen müssten, würde niemals etwas unternommen werden, da die Kosten für die Ermittlung der Auswirkungen einer Änderung die Änderung unmöglich machen würden. Zumindest wäre nichts SOLID und somit leicht zu pflegen, da Sie es niemals wagen würden, etwas zu berühren, das an mehreren Stellen verwendet werden kann; Sie würden stattdessen Ihr eigenes sehr ähnliches-aber- rollen. Integrieren Sie Ihre Minor-Change-Lösung für diesen einen Fall, verletzen Sie SRP und wahrscheinlich OCP und verwandeln Sie Ihre Codebasis langsam in einen Patchwork-Quilt.

  • nit testet die Formarchitektur auf typisch vorteilhafte Weise. Unit-Tests sind Tests, die isoliert von jeder anderen Logik durchgeführt werden. Um Ihren Code in einem Unit-Test testen zu können, müssen Sie den Code so schreiben, dass Sie ihn isolieren können. Gute Entwurfsentscheidungen wie lose Kopplung und Abhängigkeitsinjektion rütteln somit natürlich aus dem TDD-Prozess heraus; Abhängigkeiten müssen eingefügt werden, damit Sie in einem Test einen "Mock" oder "Stub" einfügen können, der die Eingabe erzeugt oder die Ausgabe für die zu testende Situation verarbeitet, ohne "Nebenwirkungen" zu verursachen. Die "Use First" -Mentalität von TDD führt im Allgemeinen zu "Coding to Interfaces", der Essenz der losen Kopplung. Diese guten Konstruktionsprinzipien ermöglichen es Ihnen dann, Änderungen in der Produktion vorzunehmen, z. B. eine ganze Klasse zu ersetzen, ohne dass große Mengen der Codebasis geändert werden müssen, um sich anzupassen.

  • nit Tests zeigen , dass der Code funktioniert, anstatt zu beweisen der Code funktioniert. Auf den ersten Blick könnte man das für einen Nachteil halten; Beweis ist doch besser als Demonstration? Die Theorie ist großartig; Die rechnergestützte und algorithmische Theorie ist die Grundlage unserer Arbeit. Ein mathematischer Beweis für die Richtigkeit eines Algorithmus ist jedoch kein Beweis für Richtigkeit der Implementierung . Ein mathematischer Beweis zeigt nur, dass Code, der dem Algorithmus entspricht, korrekt sein sollte . Ein Komponententest zeigt, dass der tatsächlich geschriebene Code genau das tut, was Sie erwartet haben, und ist somit ein Beweis dafür, dass er korrekt ist. Dies ist im Allgemeinen viel wertvoller als ein theoretischer Beweis.

Nun, alles in allem gibt es Nachteile beim Testen von Einheiten:

  • Sie können nicht alles testen. Sie können Ihr System so gestalten, dass die Anzahl der LOCs, die nicht durch einen Komponententest abgedeckt werden, minimiert wird. Es gibt jedoch ganz einfach bestimmte Bereiche des Systems, die nicht einem Komponententest unterzogen werden können. Ihre Datenzugriffsschicht kann verspottet werden, wenn sie von anderem Code verwendet wird. Die Datenzugriffsschicht selbst enthält jedoch viele Nebenwirkungen, und es ist normalerweise nicht möglich, einen Großteil (die meisten?) Eines Repositorys oder DAOs zu testen. In ähnlicher Weise sind in Code, der Dateien verwendet, Netzwerkverbindungen usw. herstellt, Nebenwirkungen integriert, und Sie können die Codezeile, die dies tut, einfach nicht einzeln testen. UI-Elemente können häufig nicht auf Einheiten getestet werden. Sie können Codebehind-Methoden wie Ereignishandler testen, Konstruktoren konstruieren und überprüfen, ob Handler angeschlossen sind. Es gibt jedoch keinen In-Code-Ersatz für einen Benutzer, der mit der Maus auf ein bestimmtes grafisches Element klickt und beobachtet, wie der Handler aufgerufen wird. Das Erreichen dieser Grenzen zwischen dem, was angemessen auf Einheit getestet werden kann und was nicht, wird als "Abkratzen des Randes des Sandkastens" bezeichnet. Darüber hinaus können Sie nur noch Integrationstests, automatisierte Abnahmetests und manuelle Tests verwenden, um das Verhalten zu überprüfen.

  • Viele Vorteile von Unit-Tests gelten nicht ohne TDD. Es ist durchaus möglich, Code zu schreiben und dann Tests zu schreiben, die den Code ausführen. Es handelt sich immer noch um "Unit-Tests". Wenn Sie jedoch zuerst Code schreiben, verlieren Sie viele der Vorteile, die mit der "Test-First" -Entwicklung verbunden sind: Code muss nicht unbedingt so aufgebaut sein, dass er leicht getestet oder sogar in der Produktion verwendet werden kann ;; Sie erhalten nicht den "Double-Check" -Denkprozess, der mit dem Schreiben des Tests und dem Nachdenken über das, woran Sie nicht gedacht haben, verbunden ist. Sie codieren nicht durch Testen. und wenn Sie Code schreiben, ihn manuell testen und sehen, dass er funktioniert, dann einen Unit-Test codieren, der fehlschlägt, was falsch ist, den Code oder den Test? Ihre Hauptvorteile sind die Verhinderung von Regressionen (Sie werden benachrichtigt, wenn Code, der zuvor seine Tests bestanden hat, jetzt fehlschlägt) und die Hochgeschwindigkeitsüberprüfung im Vergleich zu manuellen Tests. Der Verlust der anderen Vorteile von TDD kann dazu führen, dass die Verwendung von Komponententests überhaupt nicht mehr möglich ist.

  • nit-Test führt zu einem Overhead. Ganz einfach, Sie schreiben Code, um den Code zu testen, den Sie schreiben. Dies erhöht notwendigerweise den Gesamt-LOC eines Entwicklungsprojekts, und ja, der LOC für Tests kann den LOC für das tatsächliche Projekt überschreiten. Naive Entwickler und Nicht-Entwickler werden sich diesen Sachverhalt ansehen und sagen, dass die Tests Zeitverschwendung sind.

  • nit Testing erfordert Disziplin. Sie müssen Tests schreiben, die die Codebasis angemessen trainieren (gute Codeabdeckung), Sie müssen sie regelmäßig ausführen (wie bei jeder Änderung sollte die gesamte Suite ausgeführt werden) und Sie müssen alles "grün" halten ( alle Tests bestanden). Wenn Dinge kaputt gehen, müssen Sie sie entweder beheben, indem Sie Code korrigieren, der nicht den Erwartungen entspricht, oder indem Sie die Erwartungen der Tests aktualisieren. Wenn Sie die Tests ändern, sollten Sie nach dem "Warum" fragen und sich selbst sehr genau beobachten. Es ist unglaublich verlockend, fehlerhafte Behauptungen einfach so zu ändern, dass sie dem aktuellen Verhalten entsprechen, oder fehlerhafte Tests einfach zu entfernen. Diese Tests sollten jedoch auf den Anforderungen basieren, und wenn die beiden nicht übereinstimmen, haben Sie ein Problem. Wenn diese Dinge nicht erledigt werden, haben die Tests keinen Wert, wenn Sie sie jeweils verwenden, um den Code anzuzeigen, den Sie tatsächlich schreiben. Dies gilt ab dem Zeitpunkt, an dem Sie den Test zuletzt berührt haben (was beweisen sollte, dass Ihr anfänglicher Entwickler oder Ihre chirurgische Änderung das getan haben, was Sie dachten als du es geschrieben hast).

  • nit-Tests erfordern mehr Ausrüstung. Die übliche Lösung für das oben genannte Bedürfnis nach Disziplin und die natürliche Tendenz des Menschen, faul und selbstgefällig zu werden, ist ein "Build-Bot", der ein Softwarepaket "Continuous Integration" wie TeamCity, CruiseControl usw. ausführt, das Unit-Tests durchführt, berechnet Kennzahlen zur Codeabdeckung und andere Steuerelemente wie "Triple-C" (Einhaltung der Codierungskonvention, a la FxCop). Die Hardware für den Build-Bot muss einigermaßen leistungsfähig sein (andernfalls kann sie nicht mit der Rate der Code-Check-Ins mithalten, die das durchschnittliche Team durchführen wird), und die Check-In-Verfahren für den Bot müssen auf dem neuesten Stand gehalten werden (falls) Es wird eine neue Bibliothek mit Komponententests erstellt. Build-Skripte, mit denen Komponententests ausgeführt werden, müssen geändert werden, damit sie in dieser Bibliothek angezeigt werden können. Dies ist weniger Arbeit als es sich anhört, erfordert jedoch in der Regel ein gewisses technisches Fachwissen von mindestens einigen Mitarbeitern im Team, die wissen, wie die verschiedenen Build-Prozesse funktionieren (und sie daher in Skripten automatisieren und diese Skripte verwalten können). . Es erfordert auch immer noch Disziplin in Form von Aufmerksamkeit, wenn der Build "kaputt geht", und das Beheben von Problemen, die dazu geführt haben, dass der Build (korrekt) kaputt gegangen ist, bevor etwas Neues eingecheckt wird.

  • nit-Tests können dazu führen, dass Code nicht ideal aufgebaut wird. Während TDD normalerweise für die Modularität und Wiederverwendbarkeit von Code gut ist, kann es sich nachteilig auf die ordnungsgemäße Zugänglichkeit von Code auswirken. Objekte und Mitglieder, die in Produktionsbibliotheken abgelegt sind, können nicht privat oder intern sein, wenn sie direkt von Komponententests verwendet werden. Dies kann zu Problemen führen, wenn andere Codierer, die jetzt ein Objekt sehen, versuchen, es zu verwenden, wenn sie stattdessen etwas anderes in der Bibliothek verwenden sollten. Codeüberprüfungen können dabei helfen, aber es kann ein Problem sein.

  • nit-Tests verbieten im Allgemeinen Codierungsstile für die "schnelle Anwendungsentwicklung". Wenn Sie Komponententests schreiben, codieren Sie nicht "schnell und locker". Das ist normalerweise eine gute Sache, aber wenn Sie sich unter einer Frist befinden, die außerhalb Ihrer Kontrolle liegt, oder wenn Sie eine Änderung mit sehr geringem Umfang durchführen und der Stakeholder (oder Ihr Chef) sich fragt, warum all diese Kruft nur passieren muss Wenn Sie eine Codezeile ändern, kann es einfach unmöglich sein, die richtige Unit-Test-Suite zu schreiben und zu warten. Agile Prozesse helfen in der Regel dabei, indem sie den Entwicklern ein Mitspracherecht bei den Zeitanforderungen einräumen. Denken Sie daran, dass der Verkäufer nur "Ja, wir können" sagen muss und die Provisionsüberprüfung erhält, es sei denn, die Leute, die die Arbeit tatsächlich erledigen müssen, sagen "Nein, wir können nicht" und werden darauf geachtet. Aber nicht jeder ist agil und Agil hat seine eigenen Grenzen.

5
KeithS

Eine Sache, die nicht berührt zu werden scheint, ist die Komplexität des Testens verschiedener Codetypen.

Wenn Sie sich mit einfachen Ein- und Ausgängen beschäftigen, ist es im Allgemeinen einfach, Unit-Tests durchzuführen. Wenn die Tests unter Berücksichtigung der Edge-Fälle des getesteten Codes ausgewählt werden, geben sie Ihnen viel Vertrauen, dass sie richtig sind. Es wäre verrückt, keine Tests für solchen Code zu schreiben. (Beachten Sie, dass der meiste Code, der in Bibliotheken eingeht, diese Kriterien erfüllt.)

In anderen Fällen müssen Sie jedoch große Mocks erstellen, um zu testen, da der Code mit komplexen zugrunde liegenden Daten spielt (normalerweise eine Datenbank, muss es aber nicht sein) oder sehr komplexe Ausgabedaten erzeugt (denken Sie an eine Routine, die sich dreht Ein Startwert in ein Spiellevel für ein ziemlich extremes Beispiel) und Unit-Tests sind bei weitem nicht so nützlich. Alles in Ihren Testfällen abzudecken ist normalerweise ein Wunschtraum, und wenn Sie einen Fehler finden, ist dies fast immer ein Fall, an den Sie nie gedacht haben und für den Sie daher ohnehin keinen Test hätten erstellen können.

Es gibt keine Silberkugeln, alles, was als Silberkugel dargestellt wird, ist bei weitem nicht so gut, wie die Befürworter behaupten, aber das bedeutet nicht, dass es nutzlos ist.

4
Loren Pechtel

Unit-Tests sind nützlich, wenn sie richtig verwendet werden. Es gibt verschiedene Probleme mit Ihrer Logik.

"Wenn ich mich entwickle, mache ich viel Versuch und Irrtum", sagte Kevin.

Schauen Sie sich die Programmierung zufällig an. Es ist besser zu verstehen, was ein Code tun sollte, und dann durch einen Komponententest zu beweisen, dass er dies tut. Nehmen Sie nicht an, dass ein Code einfach funktioniert, weil die Benutzeroberfläche beim Ausführen des Programms nicht beschädigt wurde!

s writing unit tests for ASP.NET web forms something that is done often

Ich habe keine Kenntnis von statistischen Daten, um zu sagen, wie oft Leute Webformulare testen. Es spielt keine Rolle. Die Benutzeroberfläche ist schwer zu testen und Unit-Tests sollten auch nicht an eine Benutzeroberfläche gekoppelt werden. Teilen Sie Ihre Logik in Ebenen auf, Klassenbibliotheken, die getestet werden können. Testen Sie die Benutzeroberfläche getrennt von der Back-End-Logik.

So, question number 2: Would you guys advise me to start writing unit tests?

Ja. Sobald Sie sich an sie gewöhnt haben, beschleunigen sie Sie. Die Wartung ist weitaus zeitaufwändiger und kostspieliger als die anfängliche Entwicklungsphase. Die Wartung wird bei Komponententests auch bei Ersttests und Fehlerbehebungen erheblich unterstützt.

4
P.Brian.Mackey

Das Schreiben von Komponententests für ASP.NET Web Forms-Anwendungen ist NICHT üblich und sehr schwer durchzuführen. Dies bedeutet jedoch nicht, dass das Projekt es überspringen sollte.

Unit-Tests sind corner stones von geschäftskritischen Anwendungen und sie bieten Zuverlässigkeit und Sicherheit, dass die Kernfunktionalität wie erwartet funktioniert.

Tatsächlich können Sie Unit-Tests mit einem ASP.NET MVP-Muster , das für die Entwicklung von Webformularen verwendet werden kann, viel einfacher einführen. Es wird eine Trennung von Bedenken einführen und ability to write essential unit tests.

Einige Referenzen, die hilfreich sein könnten, sind:

4
Yusubov

Auf praktischer Ebene können Unit-Tests aus einem sehr wichtigen Grund äußerst nützlich sein: Sie können jeweils ein Bit eines Codes testen.

Wenn Sie eine ganze Reihe komplexer Schritte schreiben und am Ende debuggen, finden Sie häufig viele Fehler, und der Prozess ist im Allgemeinen schwieriger, da Sie weiter im Prozess sind. In Visual Studio können Sie einen Schnelltest erstellen, ein wenig ändern und NUR diesen Test ausführen. .. Sie wissen dann, dass sich beispielsweise eine Methode, die diese Methode aufruft, darauf verlassen kann. Das erhöht das Vertrauen.

nit-Tests beweisen nicht, dass Ihr Programm korrekt ist!: Unit-Tests prüfen auf Regressionen in sensiblem Code und ermöglichen es Ihnen, neue Methoden zu testen, die Sie schreiben.

nit-Tests dienen nicht zum Testen von Frontends: Stellen Sie sich einen Unit-Test als das kleine Projekt vor, das Sie erstellen, um eine neue Methode zu testen, die Sie schreiben, oder so, nicht als eine Bedingung, die Ihr Code benötigt treffen.

nit-Tests eignen sich hervorragend für kollaborative Umgebungen: Wenn ich einem Kollegen eine Methode zur Verfügung stellen muss, die eine völlig andere Technologie als meine verwendet, wie er sie beispielsweise von iOS aus aufruft, kann ich schnell schreiben Ein Komponententest, um festzustellen, ob die von ihm gewünschte Methode a) die korrekten Daten erneut ausführt b) gemäß seinen Spezifikationen ausgeführt wird c) keine bösen Engpässe aufweist.

4
Tjaart

Der Zweck von Komponententests besteht darin, Ihnen zu ermöglichen, Ihren Code sicher zu ändern (Refactoring, Verbesserung usw.), ohne befürchten zu müssen, dass Sie etwas im System beschädigen könnten. Dies ist sehr nützlich für große Anwendungen, wenn Sie nicht alle Auswirkungen Ihrer Codeänderung kennen (trotz loser Kopplung).

3
m3th0dman

Ich habe die Erfahrung gemacht, dass ja, Unit-Tests nützlich sind.

Beim Unit-Test geht es darum, Teile des von Ihnen geschriebenen Codes zu trennen und sicherzustellen, dass sie isoliert funktionieren. Diese Isolation kann in der Tat das Erstellen gefälschter oder nachgebildeter Objekte beinhalten, um mit dem zu testenden Objekt zu sprechen, oder auch nicht. Dies hängt stark von der Architektur Ihres Objekts ab.

Unit-Tests bieten verschiedene Vorteile:

Dies stellt in erster Linie sicher, dass die von Ihnen getesteten Einheiten so funktionieren, wie Sie als Entwickler denken, dass sie funktionieren sollten. Dies ist zwar weniger als es sich anhört: Es muss nicht unbedingt heißen, dass das Objekt ordnungsgemäß funktioniert. Nur dass es so funktioniert, wie Sie denken, dass es funktionieren sollte, ist es eine weitaus stärkere Aussage als die Trial-and-Error-Methode, die ohne Unit-Test erforderlich ist.

Außerdem wird sichergestellt, dass Einheiten weiterhin so funktionieren, wie Sie als Entwickler dachten , dass sie funktionieren sollten. Softwareänderungen, die sich auf unerwartete Weise auf Einheiten auswirken können.

Ein weiterer Nebeneffekt ist, dass die von Ihnen getesteten Einheiten isoliert arbeiten . Dies bedeutet im Allgemeinen, dass Sie mit der Programmierung auf Schnittstellen anstatt auf konkrete Klassen beginnen, die Kopplung verringern und den Zusammenhalt erhöhen: all dies sind die gängigen Merkmale eines guten Designs. Ja: Wenn Sie lediglich festlegen, dass Ihre Codeeinheiten Unit-Tests haben, wird das Design Ihres Codes natürlich verbessert.

Jedoch ...

Unit Testing ist nicht das Ende des Tests. Andere Arten von Tests sind noch erforderlich. Selbst wenn Sie beispielsweise gezeigt haben, dass Einheiten so funktionieren, wie Sie es erwarten, müssen Sie dennoch zeigen, dass jede Einheit so funktioniert, wie die Einheiten, die mit ihr sprechen, erwarten, dass sie funktionieren. Das heißt, integrieren sich Ihre Komponenten korrekt ineinander?

2
Kaz Dragon

Ich möchte dem eine neue Seite hinzufügen (eigentlich eine ziemlich alte): Unit-Tests sind nicht so nützlich, wenn Ihr Code gut gestaltet ist.

Ich weiß, dass die meisten Programmierer kein Programmdesign mehr machen, das tue ich immer noch, und ich fand, dass Unit-Tests eine ziemlich zeitaufwändige Notwendigkeit sind, um sich in eine TDD-Kultur einzufügen, aber bisher habe ich nur 1-2 Moll getroffen Fehler pro Tausende von Testzeilen meines Codes - nicht nur das, was ich geschrieben habe, sondern auch das, was offizielle Tester geschrieben haben.

Ich denke, Sie werden auch kein Programmdesign mehr durchführen - die derzeitigen Leute werden Sie unter Druck setzen, dies nicht zu tun -, aber vielleicht sollten Sie bedenken, dass der Komponententest im Vergleich zum Design eine Methode mit sehr geringem Wirkungsgrad ist.

Dies ist ein dijsktraianisches Argument: Unit-Test kann nur für ein Programm ausgeführt werden, das detailliert genug ist, um ausgeführt zu werden.

Wenn Sie Flussdiagramme/Status-/Aktionsdiagramme, Sequenzdiagramme, Objektinventare (und zuletzt UND am wenigsten Klassendiagramme) für Ihren Code zeichnen, bevor Sie ihn tatsächlich schreiben, können Sie die meisten potenziell bedrohlichen Fehler durch einfaches Nachverfolgen beseitigen Ihre Zeilen und überprüfen Sie Ihre Namen.

Heutzutage werden Klassendiagramme aus Code generiert, der Hunderte, manchmal Tausende von Klassen enthält und völlig unbrauchbar ist - alles, was mehr als 15 Elemente enthält, ist für den Menschen unerkennbar.

Sie müssen wissen, was 10 + -5 Klassen wichtig sind oder was Sie gerade tun, und in der Lage sein, Ihren Code aus mehreren Blickwinkeln zu überprüfen, wobei jedes Diagramm genau die Gesichtspunkte darstellt, die Sie betrachten, und Sie werden Tausende von Fehlern beseitigen auf Papier.

  • Einchecken eines dynamischen Codes, ob Typen erfüllt sind (indem einfach Eingabe-/Ausgabetypen in einem Flussdiagramm angezeigt und mit einem Bleistift oder einer anderen Farbe verbunden werden),
  • überprüfen, ob alle Zustände behandelt werden (indem Sie die Fülle Ihrer Bedingungen überprüfen),
  • verfolgen Sie die Linien, um sicherzustellen, dass alles ein Ende hat (jedes Flussdiagramm sollte für mathematisch Gesinnte ein vollständig definierter deterministischer Finite-State-Automat sein
  • sicherstellen, dass bestimmte Komponenten nichts miteinander zu tun haben (indem alle ihre Abhängigkeiten extrahiert werden) (gut für die Sicherheit)
  • vereinfachung des Codes durch Konvertieren von Abhängigkeiten in Assoziationen (Abhängigkeiten stammen von den Klassen, die die Mitgliedsmethoden verwenden).
  • namen überprüfen, nach gängigen Präfixen suchen, Synonyme löschen usw.

es gibt einfach so viel einfacher ...

Außerdem habe ich herausgefunden, dass meine Anwendungen benutzerfreundlicher sind, wenn sie direkt aus Anwendungsfällen stammen ... wenn die Anwendungsfälle gut geschrieben sind (Betreff des ACTOR-Verbs, Aufforderung des Betreuers, den Geldautomaten zu öffnen) ... Das

Ich habe Code mit 95 +% der Codeabdeckungen erstellt. Natürlich mache ich manchmal Unit-Tests, insb. für Grenzkontrollen in Berechnungen, aber ich muss noch ernsthafte Regressionen treffen (ernst: wird nicht innerhalb von 24 Stunden ausgelöscht), weil ich Unit-Tests nicht einmal für Refactorings verwendet habe.

Manchmal mache ich 3-4 Tage lang keine einzige Codezeile, sondern zeichne nur. Dann tippe ich an einem Tag 1500-2000 Zeilen ein. Am nächsten Tag sind sie größtenteils produktionsbereit. Manchmal werden Unit-Tests geschrieben (mit 80 +% der Abdeckung), manchmal (zusätzlich) werden Tester gebeten, zu versuchen, sie zu brechen. Jedes Mal werden einige Leute gebeten, sie zu überprüfen, indem sie sie sich ansehen.

Ich muss noch sehen, dass diese Unit-Tests etwas finden.

Ich wünschte, Design-Denken würde anstelle von TDD kommen ... aber TDD ist so viel einfacher, es ist wie mit einem Vorschlaghammer ... Design braucht Denken, und Sie sind die meiste Zeit für die Tastatur weg.

1
Aadaam

Für einfache Apps mit einer geringen Anzahl zu testender Ebenen (Hauptfenster -> Untermenü) ist das Kompilieren zum Ausführen zur Überprüfung von Änderungen möglicherweise in Ordnung.

Bei größeren Apps, bei denen die Navigation in den 30er Jahren erforderlich ist, um zu der Seite zu gelangen, die Sie testen, ist dies sehr teuer.

1