Warum schlagen automatisierte Tests in meinem Unternehmen immer wieder fehl?


178

Wir haben mehrmals versucht, automatisierte Entwicklertests in meinem Unternehmen einzuführen. Unser QA-Team verwendet Selenium, um UI-Tests zu automatisieren, aber ich wollte immer Unit-Tests und Integrationstests einführen. In der Vergangenheit freuten sich alle jedes Mal, wenn wir es versuchten, über die ersten ein oder zwei Monate. Dann, einige Monate später, hören die Leute einfach damit auf.

Einige Beobachtungen und Fragen:

  1. Funktioniert das automatisierte Testen tatsächlich? Die meisten meiner Kollegen, die früher in anderen Unternehmen gearbeitet haben, haben versucht, eine automatisierte Teststrategie zu implementieren. Ich habe noch kein echtes Softwareunternehmen gesehen, das es tatsächlich nutzt und nicht nur darüber spricht. So viele Entwickler betrachten automatisiertes Testen als etwas, das theoretisch großartig ist, aber in der Realität nicht funktioniert. Unser Business-Team würde es gerne tun, wenn die Entwickler dies sogar zu einem Preis von 30% mehr Zeit tun würden (zumindest sagen sie dies). Aber Entwickler sind Skeptiker.

  2. Niemand weiß wirklich, wie man automatisierte Tests richtig durchführt. Ja, wir haben alle die Unit-Test-Beispiele im Internet gelesen, aber sie für ein großes Projekt zu verwenden, ist etwas ganz anderes. Der Hauptschuldige ist das Verspotten / Stubben der Datenbank oder alles andere, was nicht trivial ist. Sie verbringen am Ende mehr Zeit mit Verspotten als mit dem Schreiben tatsächlicher Tests. Wenn das Schreiben von Tests dann länger dauert als das Schreiben von Code, geben Sie auf.

  3. Gibt es gute Beispiele für Unit-Tests / Systemintegrationstests, die in komplexen datenorientierten Webanwendungen verwendet werden? Irgendwelche Open Source Projekte? Unsere Anwendung ist datenzentriert, verfügt jedoch auch über zahlreiche Domänenlogiken. Ich habe den Repository-Ansatz irgendwann ausprobiert und fand ihn ziemlich gut für Unit-Tests, aber er kostete es, den Datenzugriff einfach optimieren zu können, und er fügte eine weitere Komplexitätsebene hinzu.

Wir haben ein großes Projekt von 20 erfahrenen Entwicklern durchgeführt. Dies scheint eine ideale Umgebung für die Einführung von Unit-Tests / Integrationstests zu sein.

Warum funktioniert es bei uns nicht? Wie haben Sie es in Ihrem Unternehmen geschafft?


14
Was ist Ihr Technologie-Stack?
Florian Margaine

7
Es ist nahezu unmöglich, WebForms ordnungsgemäß zu testen. Sie können ein MVP-Muster (Model / View / Presenter) verwenden, um die Präsentationslogik in eine testbare Komponente zu verschieben.
Pete

12
@MasonWheeler: In beiden Fällen haben Sie ein großartiges Argument entwickelt, das nicht akzeptierte Prämissen widerlegt: Das heißt, dass Komponententests existieren, um die Richtigkeit zu beweisen.
Steven Evers

10
@ MasonWheeler- Mit diesem Argument sollten Sie niemals eine Qualitätssicherung versuchen, da Sie niemals beweisen werden, dass es keine Fehler gibt. Das ist nicht einmal das Ziel. Eine gute Strategie für automatisierte Benutzeroberflächen- und Komponententests besteht darin, die Qualitätssicherung von Redundanztests zu befreien und ihnen die Möglichkeit zu geben, sich auf explorative Tests zu konzentrieren.
Alex

15
Ich bin schockiert, dass mehrere Leute angaben, sie hätten seit mehr als ein paar Monaten keine automatisierten Tests mehr gesehen. Ich habe für ungefähr fünf große Unternehmen in Deutschland als Berater gearbeitet und sie würden Sie entlassen, wenn Sie keine Tests schreiben. Automatisiertes Testen ist kein theoretisches Fach, es wird weltweit erfolgreich praktiziert und erhöht die Codequalität erheblich (wenn es richtig gemacht wird).

Antworten:


89

Der schwierigste Teil bei Unit-Tests besteht darin, die Disziplin dazu zu bringen, Tests zuerst / früh zu schreiben. Die meisten Entwickler sind es gewohnt, nur in Code einzutauchen. Es verlangsamt auch den Entwicklungsprozess von Anfang an, da Sie versuchen, einen Test für den Code zu schreiben. Je besser Sie jedoch testen, desto schneller. Und aufgrund der Schreibtests beginnt die Anfangsqualität des Codes höher.

Versuchen Sie zu Beginn, nur Tests zu schreiben. Mach dir am Anfang nicht so viele Gedanken darüber, Dinge zu verspotten. Halten Sie die Tests einfach. Tests sind Code und können / sollten überarbeitet werden. In diesem Sinne könnte es sich auch um das Design handeln, wenn etwas schwer zu testen ist. TDD verwendet die meisten Entwurfsmuster (nach meiner Erfahrung insbesondere das Factory-Muster).

Stellen Sie sicher, dass die Tests eine gewisse Sichtbarkeit aufweisen. Integrieren Sie sie in den Freigabeprozess. Fragen Sie während der Codeüberprüfung nach ihnen. Alle gefundenen Bugs sollten getestet werden. In diesen Dingen erstrahlt TDD.

Hier sind einige nützliche Ressourcen:

http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf

http://www.agitar.com/downloads/TheWayOfTestivus.pdf

Bearbeiten:

Eine Sache, die Sie beachten sollten, wenn Sie Tests schreiben. Sie versuchen nicht, etwas über die Implementierung des Codes anzugeben, sondern nur das Verhalten. Wenn Sie Code schreiben, testen Sie ihn ständig. Versucht, es mit Debug-Anweisungen und so weiter auszuführen. Durch das Schreiben von Tests wird dies formalisiert und es wird eine Aufzeichnung der von Ihnen durchgeführten Tests bereitgestellt. Auf diese Weise können Sie Ihre Funktionalität sicher überprüfen, ohne versehentlich einen Testfall zu überspringen, an den Sie sich in der Mitte des Entwicklungsprozesses erinnert haben.


Eine weitere Möglichkeit, dies als Diagnosefunktion einzuführen, ist der Power-On-Self-Test (POST), der fast den Code eines Kunden enthält, und nicht nur eine Reihe einfacher Tests, wie Tests und Funktionen sein sollten.
JustinC

Vermeiden Sie auch TDD-Anti-Patterns .
Gary Rowe

4
Misko Hevery hat auch einige großartige Videos auf Youtube über das Schreiben von testbarem Code, den ich für von unschätzbarem Wert befunden habe. youtube.com/watch?v=acjvKJiOvXw
Despertar

"Stellen Sie sicher, dass die Tests ein hohes Maß an Sichtbarkeit erhalten" - dies ist entscheidend für den Erfolg. Wenn niemand sehen kann, wie Ihre Tests ausgeführt werden, wird der Wert nicht angezeigt. Die Tests sollten beim Einchecken im Rahmen einer kontinuierlichen Integration automatisch ausgeführt und anschließend gemeldet werden. Ich arbeite bei Tesults ( tesults.com ) und der Grund dafür ist, dass die Sichtbarkeit von Aufpralltests enorm ist.
Geschicklichkeit M2

77

In vielerlei Hinsicht stimme ich Ihrem Team zu.

  1. Die meisten Komponententests sind von fragwürdigem Wert. Da scheint die überwiegende Mehrheit der Tests zu einfach zu sein.

  2. Es ist viel schwieriger, gut testbaren Code zu schreiben, als nur funktionierenden Code. Es gibt einen großen Prozentsatz der Entwicklergemeinde, die daran glaubt, dass es einfach funktioniert, im Gegensatz zur Code- / Designqualität an sich. Und ein noch größerer Prozentsatz, der nicht einmal weiß, was Qualitätscode ist.

  3. Das Schreiben des Unit-Test-Codes kann viel länger dauern als der eigentliche Code.

  4. Das Herausfinden, wie man den komplizierteren Code (dh das Material, an dem man wirklich interessiert ist) angemessen testet, übersteigt die Möglichkeiten vieler Entwickler.

  5. Die Durchführung von Komponententests dauert zu lange. Kleine Änderungen können große Welligkeitseffekte haben. Das Hauptziel automatisierter Komponententests besteht darin, herauszufinden, ob Änderungen den Code verletzt haben. In 99% der Fälle sind jedoch die Tests und nicht der Code das Problem.

Bei all den oben genannten Problemen gibt es immer noch keinen besseren Weg, um Codeänderungen vorzunehmen und sicher zu sein, dass etwas nicht unerwartet kaputt geht, als Ihre Tests zu automatisieren.

Einige der oben genannten Probleme können bis zu einem gewissen Grad behoben werden, indem das Lehrbuch für Komponententests nicht befolgt wird.

Viele Arten von Designs / Anwendungen lassen sich besser testen, indem Tests auf Modul- / Paketebene automatisiert werden. Nach meiner Erfahrung sind die meisten Codierungsfehler nicht darauf zurückzuführen, dass der Code in einer Klasse falsch codiert wurde, sondern darauf, dass der Codierer nicht verstand, wie seine Klasse mit anderen Klassen zusammenarbeiten sollte. Ich habe bei dieser Art von Tests viel fürs Geld gesehen. Aber auch diese Tests sind schwerer zu schreiben als Unit-Tests (Klassenlevel).

Es kommt wirklich darauf an, ob die Entwickler an den Prozess glauben oder nicht. In diesem Fall schreiben sie gute Komponententests, finden frühzeitig Fehler und sind Befürworter. Wenn sie dies nicht tun, werden ihre Komponententests im Großen und Ganzen unbrauchbar sein und keine Fehler finden, und ihre Theorie, dass Komponententests unbrauchbar sind, wird sich (in ihren Köpfen) als wahr erweisen.

Das Fazit ist, dass ich selbst seit mehr als ein paar Monaten nicht mehr gesehen habe, wie ein vollständig automatisierter Komponententest funktioniert, aber die Idee des automatisierten Komponententests besteht nach wie vor, obwohl wir selektiv entscheiden, was wirklich getestet werden muss. Dieser Ansatz hat tendenziell viel weniger Kritiker und wird von allen Entwicklern eher akzeptiert als nur von wenigen.


24
Ich stimme dem eher zu. Wir haben uns angewöhnt, Tests erst nach einer Unterbrechung durchzuführen (auch wenn diese Unterbrechung während der Entwicklung erfolgte). Niemals im Vorfeld, braucht zu viel Zeit für zu wenig Belohnung.
Izkata

5
@Izkata Der andere Ansatz, den ich erfolgreich gesehen habe, besteht darin, eine relativ kleine Anzahl von Tests auf hoher Ebene zu schreiben, die die Frobinate()Methode auf oberster Ebene aufrufen (anstelle der Dutzenden kleinerer Methoden, die darunter genannt werden), nachdem das System auf andere Weise überprüft wurde als Rauchprobe, dass keine der unteren Level-Änderungen etwas kaputt gemacht hat. Im Allgemeinen wurden bei diesen Tests dieselben Daten verwendet wie bei den Tastaturbenutzertests, damit der Kunde sehen kann, dass das System das tut, was er will. Anschließend können Codeabdeckungstools identifizieren, wo Kantenfälle noch nicht abgedeckt sind.
Dan Neely

3
Ich habe nicht "ausgewachsene automatisierte Tests" gesagt, sondern "ausgewachsene automatisierte UNIT-Tests". Großer Unterschied. Ich habe mindestens ein Jahrzehnt lang automatisierte Tests auf Modulebene durchgeführt. Unit-Tests finden auf Klassenebene statt. Ich glaube, dass ich mehr für das Geld bekomme, wenn ich Klassen teste, die zusammenarbeiten sollen, anstatt als Einzelpersonen. Aber auch dort verfolgen wir einen pragmatischen Ansatz und wählen selektiv aus, was / wo automatisierte Tests geschrieben werden sollen.
Dunk

2
Wie können Sie ohne eine gute Abdeckung durch Komponententests umgestalten? Wie können Sie verhindern, dass der Code ohne Refactoring allmählich zur Unverwaltbarkeit verkommt?
Kevin Cline

1
@Leonardo Taten sie nicht - sie hatten zu viel Angst, um etwas zu ändern. Oder sie haben all diese technischen Schulden gespart und einige Wochen / Monate später beiseite gelegt, um sie auf einmal zu lösen.
GraemeF

33

Der Hauptschuldige ist das Verspotten / Stubben der Datenbank oder irgendetwas, was nicht einfach ist.

Und da ist dein Problem.

Jeder macht gute Argumente dafür, wie Unit-Tests in Ihre Umgebung integriert werden können. Wie man Leute dazu zwingt, es genug zu tun, dass sie den praktischen Wert sehen und es "klebt". Aber wenn es sehr schmerzhaft ist und / oder keinen Nutzen bringt, bleibt es nicht haften.

Eine Datenbank auszulagern sollte kinderleicht sein. Anstatt dass Ihre Schnittstelle zu einem DB-Backup wechselt, um dessen Ergebnisse bereitzustellen, fügen Sie ein einfaches, fest codiertes Objekt ein. Wenn Sie das nicht können, hat Ihr Design / Ihre Architektur Probleme. In Ihrem Code wird davon ausgegangen, dass es sich um eine Datenbank handelt, oder Sie verfügen nicht über die Schnittstellenabstraktion, um sie zu variieren.

Dies ist nicht nur ein Test- / Qualitätsproblem. Sobald Sie den DB-Anbieter wechseln oder stattdessen in die Cloud wechseln oder nicht verbundene mobile Apps unterstützen möchten, schlägt Ihr Design einfach fehl. Wenn Sie nicht die einfachsten Fälle von Flexibilität unterstützen können, können Sie mit Sicherheit nicht die komplexeren Dinge unterstützen, die Ihr Unternehmen zwangsläufig benötigt.


4
Das Festcodieren von Datenbankrückgabewerten von einem kleinen Stub eines Scheinobjekts ist eine gute Möglichkeit, den Test von allem in der Datenbank zu isolieren, was den Code ändern und beschädigen könnte (z. B. Spaltenumbenennungen). Es ist unter bestimmten Umständen angemessen, aber es ist wichtig, eine benutzerfreundliche temporäre Testdatenbank zu haben, es sei denn, Sie möchten, dass die Dinge eines Tages kaputt gehen, wenn Sie sie ändern. Wenn Ihr Code beim Auslagern der Datenbank beschädigt wird, liegt dies an dem Code, den der Test

8
@fennec - Unit-Tests dienen nicht zum Testen der Datenbank, sondern zum Testen des Codes, dessen Funktion von den Datenbankwerten abhängt.
Telastyn

3
Alles in Ordnung und gut, bis Sie den Code testen, der die Datenbank manipuliert. : P, das für viele Leute ein großer Teil ihres Codes ist.

4
@fennec - Es ist etwas komplizierter als einfach, die Oberfläche auszublenden, um sicherzustellen, dass Ihre Schreibvorgänge das richtige Objekt schreiben. Es wird nur schwierig, wenn Ihre Klassen versuchen, SQL direkt über Ihre Schnittstelle zu senden (lesen Sie: Sie haben ein schreckliches Design).
Telastyn

5
@Telastyn Vielleicht habe ich ein Missverständnis, aber irgendwann muss eine Klasse herunterkommen und schmutzig werden und SQL schreiben oder die Datei schreiben oder die Daten oder die Schnittstelle mit der GPU senden. Die meisten Abstraktionen weisen auf einer bestimmten Ebene unvermeidbare Lecks auf. Sie sind einfach pragmatisch und nicht unbedingt schrecklich.
Warteschlange für Auszubildende

21

Sie müssen mit etwas Kleinem beginnen, das einfach zu automatisieren und von hohem Wert ist. Ziehen Sie etwas süßes, tief hängendes Obst herunter, und Sie werden in der Lage sein, den Prozess zu verkaufen. Zeigen Sie, wie jemand spät in der Nacht oder am Wochenende einen Anruf erspart hat. Dann können Sie von dort aus expandieren.

Um automatisierte Tests gut zu machen, benötigen Sie jemanden, der eine Ressource und ein Evangelist ist und der sich von höheren Management-Ebenen einkauft.

Behandeln Sie Ihre automatisierte Testentwicklung wie jedes andere agile Projekt. Führen Sie regelmäßig durchgeführte Tests durch.

Hinzufügen von Kommentar: Das ist eher ein Managementproblem. Wird der Code als "erledigt" betrachtet, bevor er dokumentiert wird? Bevor es eingecheckt wird? Bevor es Unit-Tests beinhaltet und besteht?

Wie Sie das angehen, hängt wirklich von Ihrer Rolle ab. Bist du ein Peer? Wenn ja, zeigen Sie anderen, wie sie Ihren Code leichter wiederverwenden und warten können. Bist du eine Spur? Wählen Sie Ihren Programmierer aus, der die meisten Code-Probleme hat, und helfen Sie ihm, Tests hinzuzufügen, um diese Probleme zu vermeiden. Bist du ein Boss? Stellen Sie als Standard ein, dass "der Code erst ausgeführt wird, wenn die Komponententests abgeschlossen sind.


17
"Ziehen Sie etwas süßes, tief hängendes Obst herunter, und Sie werden den Prozess verkaufen können.": Ich denke, sie haben bereits dieses Stadium erreicht (sie sahen potenzielle Vorteile bei der Verwendung von Komponententests), und deshalb waren sie überzeugt, es zu geben ein Versuch. Das Problem ist eher, wie man die niedrig hängenden Früchte skaliert, um systematisch Unit-Tests durchzuführen. Das einzige Projekt, an dem ich gearbeitet habe, in dem Komponententests systematisch verwendet wurden, hatte mehr Komponententestcode als der tatsächliche Produktcode. Wenn ein Team nicht bereit ist, mehr Zeit für die Codierung von Unit-Tests als für den eigentlichen Anwendungscode zu verwenden, funktioniert der Ansatz nach IMO wahrscheinlich nicht.
Giorgio

4
Das ist eher ein Managementproblem. Wird der Code als "erledigt" betrachtet, bevor er dokumentiert wird? Bevor es eingecheckt wird? Bevor es Unit-Tests beinhaltet und besteht? Wie Sie das angehen, hängt wirklich von Ihrer Rolle ab. Bist du ein Peer? Wenn ja, zeigen Sie anderen, wie sie Ihren Code leichter wiederverwenden und warten können. Bist du eine Spur? Wählen Sie Ihren Programmierer aus, der die meisten Code-Probleme hat, und helfen Sie ihm, Tests hinzuzufügen, um diese Probleme zu vermeiden. Bist du ein Boss? Stellen Sie als Standard ein, dass "der Code erst erstellt wird, wenn die Komponententests abgeschlossen sind.
Überspringen Sie Huffman

1
@SkipHuffman Ihr Kommentar sollte als Bearbeitung zur aktuellen Antwort hinzugefügt werden.
Radu Florescu

15

Befolgen Sie diese Grundregeln. Tests:

  1. muss regelmäßig laufen! Sie können Tests für jedes Build, vor / nach jedem Einchecken oder einfach jeden Morgen durchführen. Das automatische Auslösen ist dem manuellen Auslösen vorzuziehen . Während theoretisch jeder im Team dafür verantwortlich sein kann, dass Tests durchgeführt werden, passiert dies wahrscheinlich nicht oft genug, wenn es nicht automatisiert ist! Und wenn Sie Ihre Tests nicht oft genug durchführen, finden beide die Fehler zu spät und führen zu vielen fehlerhaften Tests, was zu Punkt 2 führt:

  2. Sie werden immer noch nur erfolgreich sein, wenn diese Tests, die jetzt regelmäßig durchgeführt werden, nicht im Wege stehen . Unter Tests verstehen wir:

    ein. Es darf nicht zu lange dauern (subjektiv) für den Wert, den sie bieten! Machen Sie Ihre Tests blitzschnell. Lassen Sie nicht zu, dass Leute Tests einchecken, die eine Verschwendung Ihrer Zeit sein werden, um sie laufen zu lassen!

    b. darf nicht unzuverlässig sein. Vermeiden Sie nach Möglichkeit Multithread-Tests. Wenden Sie technische Methoden auf Ihre Tests an, genau wie auf Ihren anderen Code: insbesondere - Code-Überprüfung Ihrer Tests!

    c. muss nicht schwieriger zu reparieren und zu warten sein als der tatsächlich getestete Code. Ihre Codierungsgeschwindigkeit wird wirklich zum Erliegen kommen, wenn Sie für eine winzige Änderung der Codebasis um eine Zeile 10 verschiedene Tests korrigieren müssen.

Und schließlich Regel Nummer 3. Tests dürfen nicht nur keinen negativen Wert liefern, wie in Regel 2, sondern müssen auch einen positiven Wert liefern. Tests ...

  1. muss dir tatsächlich etwas sagen, das dir wichtig ist, wenn sie versagen! (Keine Tests mit obskuren Fehlermeldungen oder nur lächerlichen Beschwerden wie "Sie haben vergessen, den Test auf einem Windows 2008-Computer auszuführen"!).

Eine beliebte Möglichkeit, gegen Regel 3 zu verstoßen, besteht darin , das Falsche zu testen . Dies ist manchmal darauf zurückzuführen, dass ein Test zu groß oder zu unscharf ist. In der Regel wird jedoch nichts getestet, was einem Kunden wichtig ist, und es werden irrelevante Implementierungsdetails getestet. (Aber manchmal macht das Testen von Implementierungsdetails auch einen effizienten Test aus - IMO ist es nur eine Übung, zu entscheiden, welche.)

Fazit: Diese Grundregeln weisen Sie in die generelle Richtung einer nachhaltigen Testdisziplin, nach der Sie sich sehnen. Fragen Sie sich beim Testen, ob dieser Test wirklich nachhaltig und wartbar ist. Merken:

  • Wenn Tests nicht nachhaltig sind, werden sie nicht mehr verwendet und verursachen unnötigen Arbeitsaufwand
  • Wenn Tests nicht nachhaltig sind, hören Sie auf, Tests durchzuführen, und Ihr Team kann die Tests nicht mehr verbessern! Und letzter Punkt:

Testen ist eigentlich schwer. Sie sollten damit rechnen, dass die Tests Ihres Teams im Grunde genommen schlecht werden, wenn Sie anfangen, Tests zu schreiben . Lass dich nicht entmutigen. Sie werfen alte Tests weg, wenn Sie bemerken , dass sie saugen und sind nicht nachhaltig.


12

1. Funktioniert es wirklich

Ja, wenn es richtig gemacht wird. Der Punkt ist, dass Tester ihre automatisierten Skripte anpassen und erweitern müssen, nachdem Ingenieure neue Funktionen implementiert haben.

2. Niemand ist wirklich erfahren oder weiß, wie man automatisierte Tests richtig durchführt.

Holen Sie sich einen Berater (jemand, der weiß, wie es richtig gemacht wird). Oder investieren Sie mehr Zeit. Die Alternative besteht darin, ein größeres Testteam zu haben, das die gleichen Tests manuell durchführt (was fehleranfällig ist).

3.Wir haben ein großes Projekt mit 20 erfahrenen Entwicklern, die daran arbeiten. Es sollte also eine großartige Umgebung sein, um Unit-Tests / Integrationstests einzuführen. Warum funktioniert es bei uns nicht? Wie haben Sie es in Ihrem Unternehmen geschafft?

Ich würde sie nicht als "erfahrene Entwickler" bezeichnen, wenn sie sich weigern, Komponententests durchzuführen. Es gibt viele großartige Artikel über die positiven Vorteile des Testens (sowohl Unit- als auch Integrationstests), und am Ende läuft es darauf hinaus, wie viel ein Fehler Ihr Unternehmen kostet . Zum Beispiel arbeite ich in einem Unternehmen, in dem Qualität zählt, daher sind Unit- und Integrationstests unvermeidbar. Sie können leicht viele Artikel finden, die besagen, dass nur Unit-Tests die Anzahl der Bugs um 30% reduzieren! (Eigentlich liegt es im Bereich von 20-90%, im Durchschnitt bei 30%, aber es ist immer noch viel.)

Um es in Ihrem Unternehmen zum Laufen zu bringen, stellen Sie entweder einen Berater ein oder weisen Sie diese Aufgabe einem leitenden Ingenieur zu (es wird eine Weile dauern, bis er sie erledigt hat). Und dann zwingen Sie alle, sich an die Regeln zu halten.


20
Ich muss darauf hinweisen, dass praktisch ALLES funktioniert, "wenn es richtig gemacht wird". Dies ist jedoch nur für eine sehr kleine Minderheit der Bevölkerung von großem Nutzen. Damit ein Prozess wirklich behaupten kann, dass er funktioniert, muss er auch "irgendwie" funktionieren.
Dunk

11
Ich werde darauf hinweisen, dass eine Überverallgemeinerung der Situation jedes Einzelnen nach seinen Wünschen (dh ich würde sie nicht als "gut erfahrene Entwickler" bezeichnen) nicht nur Ihre mangelnde Erfahrungsbreite zeigt, sondern auch nicht sehr produktiv ist. Jede Branche hat ihre eigene Definition von "Werken"; und welcher Abschluss auf der Ebene der Einheit, der Integration und des Systems geprüft werden muss. Viele "außergewöhnlich gute" Entwickler sind zu der Erkenntnis gelangt, dass Unit-Tests im Vergleich zu automatisierten Integrationstests nur wenig kosten. Sie erkennen auch, dass dies wahrscheinlich nur für ihre spezifische Branche gilt.
Dunk

11
"Ich würde sie nicht als" erfahrene Entwickler "bezeichnen, wenn sie sich weigern, Komponententests durchzuführen." Dies ist nur der Irrtum der No True Scotsman. Die Software-Branche kam jahrzehntelang ohne Unit-Tests aus und die meisten Branchen kommen auch heute noch ohne aus. Es mag eine gute Idee sein, aber es ist einfach nicht obligatorisch.
Noah Yetter

1
"Verschwenden Sie keine Zeit mit Komponententests": Ich würde dies als "Verschwenden Sie keine Zeit mit unnötigen Komponententests" umformulieren. Blindes Testen von Einheiten kann zu einer enormen Zeitverschwendung führen.
Giorgio

1
@Dunk Ich hasse das ganze TDD-Phänomen "Test first everything" wirklich, aber ich kann Ihrer ersten Aussage nicht zustimmen. Entweder machst du etwas richtig oder nicht. Sie können einen Einheitentest gut machen und vielleicht die Vorzüge davon sehen, aber Sie werden nie die Vorzüge von etwas sehen, das halbherzig gemacht wird.
Erik Reppen

10

Dies sind viele Gründe, warum die Einführung automatisierter Tests fehlschlagen kann. Ich denke, dass es auf die Tatsache hinausläuft, dass Programmierer dazu neigen, ihre Codierungsgewohnheiten nicht zu ändern, und nicht in der Lage sind, Unit-Tests vollständig zu akzeptieren.

Viele Leute, die mit automatisierten Tests beginnen möchten, versuchen, sie für eine vorhandene Codebasis einzuführen. Sie werden versuchen, Integrationstests zu schreiben, die viele Funktionen der vorhandenen Anwendung gleichzeitig testen. Solche Integrationstests sind bekanntermaßen zu schwierig und zu teuer in der Wartung. Hinweis: Führen Sie automatisierte Tests für eine neue Codebasis ein.

Unit-Tests sind gute Tests, die automatisiert werden müssen. Alles oben Gesagte (Integrationstests, Komponententests, Systemtests) kann auch automatisch getestet werden. Das Kosten-Nutzen-Verhältnis sinkt jedoch rapide, je mehr Funktionen gleichzeitig getestet werden. Dieser negative Effekt wird verstärkt, wenn Sie solche Tests auf schlecht getesteten Funktionen aufbauen. Hinweis: Führen Sie automatisierte Tests auf der Ebene von Komponententests ein und erstellen Sie automatisierte Integrationstests auf einer soliden Grundlage von Komponententests .

Von den oben genannten Punkten hängt ein Großteil des Erfolgs automatisierter Tests davon ab, wie effektiv die Komponententests sind. Sie haben effektive Unit-Tests, wenn Sie sich mit Unit-Tests produktiv fühlen. Wenn Menschen mit Unit-Tests beginnen, tendieren sie dazu, ihre vorhandenen Code- und Codierungsgewohnheiten in Unit-Tests umzurüsten. Ironischerweise ist dies der schwierigste Weg, Unit-Tests zu lernen. Außerdem müssen Sie beim Testen von Einheiten die Art und Weise ändern, in der Sie codieren (z. B. unter Anwendung der SOLID-Prinzipien ). Die meisten Programmierer hören bald auf, Komponententests zu schreiben, da sie der Meinung sind, dass die Lernkurve zu steil ist, und finden es umständlich, Komponententests um einen nicht so testbaren Code zu schreiben. Hinweis: Lernen Sie Unit-Tests von Grund auf mit neuem Code und gehen Sie auf die Tatsache ein, dass Sie Ihre Codierungsgewohnheiten ändern müssen.

Es gibt viele andere Faktoren, aber ich habe festgestellt, dass es für die meisten Programmierer schwierig ist, die Art und Weise zu ändern, in der sie programmieren. Ohne Test geschriebener Code sieht einfach anders aus. Wenn Sie Ihren Code nicht in ein testbares Design integrieren können, können Sie höchstwahrscheinlich keine effektiven Komponententests schreiben. Dies zerstört den Boden für effektive automatisierte Tests.

Ich habe das selbst erlebt und bin jetzt glücklich, in einem Unternehmen zu arbeiten, das erfolgreich automatisierte Tests eingeführt hat. Ich könnte viel mehr über die anderen Faktoren schreiben, aber ich denke, dass Codierungsgewohnheiten und Unit-Tests die wichtigsten sind. Zum Glück gibt es andere, die mehr Erfahrung als ich haben und Bücher mit ihrem Know-how füllen. Eines dieser Bücher ist Brownfield Application Development in .NET, das ich wirklich empfehlen kann, da Sie den Microsoft-Technologie-Stack verwenden.


Introduce automated tests on the unit test level and build automated integration tests on a solid foundation of unit tests.+1
c69

10

Eine Sache, die ich in den obigen Antworten nicht klar angesprochen gesehen habe, ist, dass Unit-Tests im Wesentlichen ein öffentliches Gut und private Kosten sind. Ich habe eine Blog - Post über sie geschrieben hier .

Es kommt darauf an, dass eine Reihe von Tests dem Team oder einem einzelnen Entwickler zugute kommt, während das Schreiben des Tests für denjenigen , der den Test durchführt , die meiste Zeit Kosten verursacht.

Kurz gesagt, es gibt keinen Grund für einen einzelnen Entwickler, dies zu tun, es sei denn, das Schreiben des Tests wird auf irgendeine Weise erzwungen - und die obigen Antworten führen eine Reihe von verschiedenen Möglichkeiten auf, dies zu tun.

In einem Unternehmen, in dem ich gearbeitet habe, war das Schreiben von Komponententests für die Bereitstellung eines Features erforderlich. Neuer Code wurde nur akzeptiert, wenn ein Komponententest Teil des Commits oder einer neuen Funktion war. Für jede "Aufgabe", die einem Entwickler übertragen wurde, wurden kurze Codeüberprüfungen durchgeführt. Es kann sich lohnen, eine ähnliche Richtlinie an Ihrem Arbeitsplatz umzusetzen.


8

Es ist interessant, dass das Geschäft mehr Pro-Testing als Entwickler ist! Es scheint mir, dass Ihre größte Herausforderung darin besteht, den Widerstand Ihrer Entwickler gegen Veränderungen zu überwinden. Sie müssen ihr Berufsverständnis neu definieren, um auch Unit-Tests durchführen zu können.

Nichts kann Ihnen mehr helfen als frühe Unit-Test-Erfolge, damit Ihre Entwickler ihren Widerstand gegen das Schreiben dieser Tests überwinden können. Wenn Sie sie dazu drängen, etwas Neues zu tun, stellen Sie sicher, dass Sie zuerst für etwas mit einer fast garantierten Belohnung drängen.

@SkipHuffman hat das angesprochen, aber ich werde es direkt sagen. Einige Dinge eignen sich viel besser für automatisierte Tests als andere. Beim ersten Durchgang würde ich weder die Datenbank noch die Benutzeroberfläche testen. Eingaben aus einer Datenbank können äußerst schwierig einzurichten und zu entfernen sein. UI-Ausgabetests werden in der Regel schnell durch Änderungen des Erscheinungsbilds unterbrochen, die für Ihre Tests völlig irrelevant sind.

Was ich als "Middleware" bezeichne, ist perfekt für Unit-Tests. Code mit klar definierten Eingabe- und Ausgabebedingungen. Wenn Sie dem DRY-Prinzip (Don't Repeat Yourself) folgen, haben Sie einige kleine Klassen oder Funktionen geschrieben, um wiederkehrende Probleme zu lösen, die nur für Ihre Anwendung gelten.

Unit-Tests sind ein hervorragendes Tool, um das Risiko zu begrenzen, dass vorhandene interne Komponenten geändert werden. Schreiben Sie Unit-Tests, bevor Sie eine interne Komponente ändern, die schon lange funktioniert hat. Diese Tests belegen, dass die aktuell funktionierende Funktionalität erhalten bleibt. Wenn Sie Ihre Änderung vorgenommen haben und alle Komponententests bestanden sind, wissen Sie, dass Sie nichts "Downstream" gebrochen haben. Wenn Sie ein Downstream-Problem finden, fügen Sie einen Komponententest hinzu!

Ron Heifitz würde sagen , "Konflikte in den Werten, die die Menschen vertreten, anzugehen oder die Kluft zwischen den Werten, für die die Menschen stehen, und der Realität, der sie gegenüberstehen, zu verringern. Adaptive Arbeit erfordert eine Änderung der Werte, Überzeugungen oder Verhaltensweisen." Nachdem Sie den menschlichen Widerstand gegen Veränderungen überwunden haben, können Sie gegebenenfalls in schwierigere Testbereiche verzweigen.


6
"Überwinde den Widerstand deiner Entwickler gegen Veränderungen": Nicht jeder Widerstand ist ohne Grund und man sollte eine ehrliche Diskussion nicht vermeiden, indem man das Argument "Widerstand gegen Veränderungen" verwendet.
Giorgio

7

Eine Sache beim automatisierten Testen ist, dass Sie Code schreiben müssen, um testbar zu sein. Dies ist an und für sich keine schlechte Sache (in der Tat ist es gut, weil es von vielen Praktiken abhält, die in der Regel vermieden werden sollten), aber wenn Sie versuchen, Komponententests auf vorhandenen Code anzuwenden, ist dies wahrscheinlich nicht der Fall wurde auf überprüfbare Weise geschrieben.

Dinge wie Singletons, statische Methoden, Registries, Service Locators und so weiter führen zu Abhängigkeiten, die nur sehr schwer auszumachen sind. Verstöße gegen das Gesetz von Demeter bedeuten, dass zu viele Teile Ihrer Codebasis zu viel darüber wissen, wie andere Teile Ihrer Codebasis funktionieren, was zu weiteren versteckten Abhängigkeiten führt, die möglicherweise schwer zu knacken sind. All diese Dinge machen es schwierig, ein Modul vom Rest der Codebasis zu isolieren, und wenn Sie Ihre Module nicht isoliert testen können, verlieren Unit-Tests viel an Wert. Wenn ein Test fehlschlägt, liegt dies an einem Fehler im zu testenden Gerät oder an einem Fehler in einer seiner Abhängigkeiten, oder möglicherweise daran, dass die Daten, die über eine abhängige Datenquelle abgerufen werden, nicht den Erwartungen des Testschreibers entsprechen ? Falls Sie können'

Die meisten Codebasen, die ich gesehen habe und die nicht für Komponententests entwickelt wurden, sind in der Regel von Natur aus nicht testbar, da sich Codierer eher darauf konzentrieren, den Code so zu gestalten, wie sie es erwarten, als die Arbeit zu leisten, die erforderlich ist, um die Kopplung und die Abhängigkeiten explizit zu halten . Code, der unter Berücksichtigung von Komponententests geschrieben wurde, sieht normalerweise ganz anders aus.

Viele Leute gehen naiv mit Unit-Tests um, wenn sie zum ersten Mal damit beginnen. Sie denken, sie können einfach eine Menge Tests für eine vorhandene Codebasis schreiben und alles wird gut, aber es funktioniert nie so, weil die oben genannten Probleme. Sie stellen fest, dass sie in Unit-Tests übermäßig viele Setups ausführen müssen, um überhaupt ausgeführt zu werden, und die Ergebnisse sind häufig fragwürdig, da die fehlende Isolation im Code bedeutet, dass Sie nicht nachvollziehen können, was einen Testfehler verursacht hat. Sie tendieren auch dazu, zunächst zu versuchen, "clevere" Tests zu schreiben, die einen sehr abstrakten Aspekt der Funktionsweise des Systems demonstrieren. Dies kann zum Scheitern führen, da ein "cleverer" Komponententest selbst eine potenzielle Fehlerquelle darstellt. Ist der Test aufgrund eines Fehlers im getesteten Modul fehlgeschlagen? oder wegen einem fehler im test? Ein Test sollte so qualvoll einfach sein, dass es offensichtlich keine Möglichkeit gibt, dass sich ein Fehler darin versteckt. Tatsächlich sind die besten Tests selten länger als zwei Zeilen. Die erste Zeile weist das zu testende Gerät an, etwas zu tun. Die zweite Zeile gibt an, dass das, was getan wurde, das war, was erwartet wurde.

Wenn es Ihrem Team ernst ist, Unit-Tests einzuführen, ist es nicht ratsam, mit einem vorhandenen Projekt zu beginnen. Die bestehenden Projekte Ihres Teams sind ohne größere Umgestaltung wahrscheinlich nicht testbar. Sie sollten besser ein neues Projekt als Grundlage für das Erlernen von Unit-Tests verwenden, da Sie einen sauberen Plan haben, mit dem Sie arbeiten können. Sie können die neue Codebasis so entwerfen, dass die Abhängigkeitsinjektion Singletons, Registries und anderen solchen versteckten Abhängigkeiten vorgezogen wird. Sie können sie so schreiben, dass sie von Schnittstellen anstelle von Implementierungen usw. abhängt. Sie können (und sollten) die Tests auch neben den zu testenden Code schreiben, da das anschließende Schreiben der Tests zu Komponententests führt, die sicherstellen, dass das getestete Modul das tut, von dem Sie glauben, dass es dazu bestimmt ist, und nicht diejenigen, die es testen Was die Spezifikationen sagen, sollte es tun.

Sobald Sie mit Unit-Tests ein gewisses Maß an Sicherheit erlangt haben, wird Ihr Team wahrscheinlich beginnen, die Fehler im vorhandenen Code zu erkennen, die Hindernisse für Unit-Tests darstellen werden. Dies ist der Zeitpunkt, an dem Sie beginnen können, vorhandenen Code zu überarbeiten, um ihn testbarer zu machen. Seien Sie nicht ehrgeizig und versuchen Sie, dies alles auf einmal zu tun, oder versuchen Sie, ein System zu ersetzen, das mit einem völlig neuen funktioniert. Suchen Sie einfach die Teile der Codebasis, die leicht getestet werden können (diejenigen, die keine haben) Abhängigkeiten oder wo die Abhängigkeiten offensichtlich sind) und schreiben Sie Tests für diese. Ich weiß, dass ich gesagt habe, dass das Schreiben eines Tests neben Code dem Schreiben von Tests nach dem Schreiben vorzuziehen ist, aber selbst ein später geschriebener Test hat immer noch Wert als Ausgangspunkt. Schreiben Sie die Tests so, als wüssten Sie nichts anderes über die Funktionsweise der Klasse als die in den Spezifikationen angegebenen. Wenn Sie die Tests ausführen und Fehler feststellen, ist entweder die Spezifikation oder die Implementierung falsch. Überprüfen Sie beide, um festzustellen, was falsch ist, und aktualisieren Sie entweder den Test oder den Code entsprechend.

Sobald Sie die tief hängenden Früchte gepflückt haben, beginnt Ihre eigentliche Arbeit. Sie müssen nacheinander die versteckten Abhängigkeiten in Ihrer Codebasis suchen und korrigieren. Werden Sie zu diesem Zeitpunkt nicht zu ehrgeizig, bleiben Sie einfach bei einem Modul oder auch nur einem einzelnen Problem in einem Modul, bis die Hindernisse für das Testen behoben sind und Sie mit dem nächsten Schritt fortfahren können.

TL: DR: Die meisten Leute denken, dass das Testen einfach ist und dass Sie Tests einfach in vorhandenen Code nachrüsten können. Diese beiden Annahmen sind falsch. Wenn Sie sich auf ein Projekt einlassen, um Unit-Tests in Ihre Projekte zu integrieren, sind Sie mit größerer Wahrscheinlichkeit erfolgreich.


Tipp: setzen Sie die TL; DR: ganz oben - ich musste Ihren ganzen Beitrag lesen, nur um dorthin zu gelangen! (die irgendwie den Punkt besiegt)
gbjbaanb

4
  • Gibt es in Ihrem Unternehmen jemanden mit umfassender Erfahrung im automatisierten Testen?

Andernfalls schlagen automatisierte Testinitiativen wahrscheinlich fehl. Automatisiertes Testen ist eine Fähigkeit, wie viele andere Fähigkeiten im Programmieren, und wenn Sie niemanden haben, der Erfahrung damit hat, ist es nicht einfach zu sagen, ob ein automatisierter Test ein guter automatisierter Test mit echtem Wert ist oder ein schlechter Test Versagen Sie nach dem Zufallsprinzip / erfordern Sie häufige Updates / üben Sie keinen interessanten Code aus.

  • Hat das jemand Führungskraft? Können sie Veränderungen fordern?

Wenn niemand zuhört, spielt es keine Rolle, ob der Test nicht gut ist. (Beachten Sie, dass die Führungsstärke nicht formalisiert werden muss. Ein Team zu haben, das sich darum kümmert, ist auch gut.)

  • Entwickeln Sie Tools und Prozesse, um das automatisierte Testen einfacher implementieren und in den Entwicklungszyklus integrieren zu können?

Entwickler sind faul. Sie müssen die Dinge, die Sie von ihnen erwarten, leicht und die Dinge, die Sie nicht von ihnen erwarten, schwieriger machen. Sie sollten sicherstellen, dass die Testbibliotheken die Durchführung der mit dem Einrichten und Herunterfahren von Tests verbundenen Aufgaben, insbesondere der umgebungsbezogenen Einrichtung, wie Testdatenbanken oder dergleichen, vereinfachen. (Das Verspotten der Datenbank wird in einigen dieser Kommentare erörtert, sollte jedoch mit Vorsicht verwendet werden. Eine echte Datenbank sollte einfach zu starten sein und Sie können das Zusammenspiel von Komponenten und Prozesslebenszyklen testen, was häufig wichtiger und effektiver ist als Unit-Tests ein individueller Datenzugriff.)

Sie sollten auch sicherstellen, dass Ihre IDEs eine gute Möglichkeit haben, die Testsuite zu starten. Sie sollten die Testsuite häufig ausführen, damit die Leute bemerken, wenn sie fehlschlägt, anstatt sie im Elend verweilen zu lassen. Entwickler reagieren auch gut auf Feedback, z. B. ein automatisiertes Integrationssystem, das ihre Änderungen zurücksetzt, wenn sie einen Test gebrochen haben. Oder besser, positives Feedback: Ein automatisiertes Integrationssystem, das Fehler erkennt und Sie davor bewahrt, Dinge zu beschädigen.


Ich finde es nicht fair zu sagen, dass Entwickler faul sind. Vielleicht ist das nach Ihrer Erfahrung der Fall, aber es ist sicherlich keine universelle Wahrheit.
Sam

4

Erstens, wenn Ihre Entwickler den Wert Ihrer Tests nicht sehen, liegt dies wahrscheinlich daran, dass Ihre Tests nicht wertvoll sind, und nicht daran, dass Ihre Entwickler für ihren Wert oder den Wert von Tests im Allgemeinen blind sind. Unter seinen Evangelisten besteht die Tendenz zu glauben, dass die testgetriebene Entwicklung nicht scheitern kann, sondern nur von faulen, faulen Entwicklern. Ich halte das für falsch und kontraproduktiv.

Als ich in die testgetriebene Entwicklung eingeführt wurde, bedeutete dies effektiv, einen Test zu schreiben, um sicherzustellen, dass eine Methode, die niemals versagt, niemals versagt. Was zunächst schön ist, weil Sie einen schönen grünen Scheck und ein Gefühl der Leistung bekommen. Später, nachdem Sie den Code überarbeitet haben, haben Sie Dutzende von wütenden roten X, von denen keines mehr aussagt, als dass sich der Code geändert hat, dass die Tests nicht mehr gültig sind und dass Sie viel Zeit damit verschwendet haben, sie zu schreiben.

Das wollen Sie vermeiden.

Seitdem habe ich einen anderen Ansatz für Tests gewählt. Anstelle eines Schnittstellenimplementierungspaares habe ich ein Schnittstellen-, Implementierungs-, Test-Triple . Die Schnittstelle legt das Verhalten fest, die Implementierung führt das Verhalten aus, der Test prüft das Verhalten.

Ich nehme an, es scheint offensichtlich, aber für mich unterscheidet es zwischen dem Code, für den Sie nachweisen müssen, dass er wie angegeben funktioniert, und dem Code, den Sie möglicherweise so viel oder so wenig testen, wie Sie für angemessen halten. Der Code, den Sie nachweisen müssen, ist die Schnittstelle, die Sie nach außen bieten. Der Rest ist Ihre Sache allein.

In diesem Fall würde ich die Entwickler fragen, ob sie eine natürliche Unterteilung im Code sehen, wo diese Art von Test angebracht wäre. Gibt es eine Schnittstelle, die Team A implementiert und von Team B verwendet wird? In diesem Fall liegt es im Interesse von Team B, sicherzustellen, dass sich die Benutzeroberfläche wie erwartet verhält. Bitten Sie Team B, einen Test dafür zu schreiben, und bitten Sie Team A, sicherzustellen, dass die Implementierung dem Test entspricht. oder, falls dies nicht der Fall ist, und dies absichtlich nicht der Fall ist, die unerwartete Änderung mit dem anderen Team zu besprechen, damit es sich darauf vorbereiten kann.

Ich denke, dies würde den Wert des Tests veranschaulichen. Es ist kein Selbstzweck, trotz schöner grüner Karos. Es besteht darin, das Versprechen, das ein Entwickler einem anderen gegeben hat, deutlich zu machen und sicherzustellen, dass das Versprechen zur Zufriedenheit beider eingehalten wird.


1
Ich mag Code, den ich besser lesen kann als Code, von dem jemand glaubte, er müsse bis in die kleinsten Einzelheiten getestet werden.
Erik Reppen

1
Die schönen grünen Häkchen, die ich fühle, sind das Problem - es macht das Testen zu einer Art Spiel.
gbjbaanb

2

Das Hinzufügen zahlreicher Komponententests zu einem bereits vorhandenen Großprojekt ist harte Arbeit. Wenn Sie bereits ein gutes Spott-Framework gefunden haben, das für Sie funktioniert, sollten Sie das schwierigste Problem gelöst haben.

Ich schlage vor, Tests hinzuzufügen, während Sie Funktionen hinzufügen / Fehler beheben. Das Beheben von Fehlern ist am einfachsten. Schreiben Sie einen Test, der aufgrund Ihres Fehlers fehlschlägt, und beheben Sie den Fehler. Gleichzeitig werden Sie wahrscheinlich feststellen, dass Sie einige einfachere Tests schreiben, die bestanden werden. Natürlich möchten Sie dafür wirklich ein kleines und einfach zu testendes Stück Code verwenden.

Wenn sich die Leute erst einmal daran gewöhnt haben, Tests für die einfacheren Dinge zu schreiben, sollten Sie hoffentlich feststellen, dass sie ihren Code schreiben, um besser testen zu können.

Ich würde auch empfehlen, dass Sie die Codeabdeckung Ihrer Tests messen (ich habe in der Vergangenheit Cobertura für Java verwendet). Sie möchten einen Continuous Integration Server, der die Tests ausführt und die Metriken regelmäßig erstellt (jeden Tag, bei jedem Check-in). Wenn Ihre Mitentwickler daran interessiert sind, möchten sie, dass die Abdeckung im Laufe der Zeit zunimmt, und sie können die klaffenden Abdeckungslöcher in einigen von Ihnen erkennen


2

Ich denke, Sie müssen vielleicht das lange Spiel spielen. Eine Sache, die Sie tun können, um eine gewisse Akzeptanz zu erhalten, ist zu versuchen, das nächste von Ihnen geschriebene Feature ausführlich zu testen und dann die Anzahl der Fehler im Laufe der Zeit zu verfolgen. Sie sollten hoffentlich feststellen, dass die Hauptfehler frühzeitig erkannt werden (insbesondere, wenn Sie dies mit Test-Driven Design kombinieren) und die Anzahl der Regressionen sehr gering sein sollte. Vergleichen Sie nach einem Zeitraum von beispielsweise einem Jahr die Statistiken mit nicht einheitlich getesteten Funktionen mit ähnlicher Komplexität. Wenn Sie nachweisen können, dass die Anzahl neuer Bugs und Regressionen erheblich geringer ist, haben Sie dies finanziell begründet, und es wird für das Produktteam schwieriger, dies zu ignorieren.

Ich hatte eine Situation, in der ich TDD und Unit-Tests für eine wichtige Funktion verwenden konnte. Nach dem Ende der Entwicklungsphase wurde in über 5 Jahren kein einziger Fehler gemeldet. Als eine neue - und riskante - Erweiterung angefordert wurde, konnte ich diese implementieren und alle Regressionen in den Unit-Tests erfassen.


1

Ich bin der festen Überzeugung, dass der Wert von Komponententests von vielen Teams aufgrund mehrerer Faktoren, von denen viele bereits in den Antworten hervorgehoben wurden, weitgehend unterschätzt wird.

Häufig stehen Entwickler unter dem Druck, "Dinge zu erledigen". Daher ist der Nachweis, dass ein Codeblock funktioniert, ein ausreichender Beweis für den Kunden. Dies gilt fast immer für Beratungsunternehmen und von Menschen geleitete Qualitätssicherung: Wenn der Kunde keine Einheitentests benötigt und eine Live-Demo für ausreichend hält, ist der Kunde völlig gescheitert, da er die Genehmigung für Code unterzeichnen wird, der Fehler verbergen könnte.

Oft sind Entwickler frustriert. Ein Programmierer zu sein, ist eine schwere Aufgabe: Eine Aufgabe zu erledigen und zur nächsten zu gehen, ist zufriedenstellend, deshalb wollen sich alle beeilen und fertig werden. Bis sie von einem Bus mit einem großen Fehler getroffen werden, der Monate nach der ursprünglichen Qualitätssicherung auftritt. In diesem Szenario ist die automatisierte und kontinuierliche Qualitätssicherung eher ein Problem des Managements als der Entwickler (sie werden trotzdem für ihre Arbeit bezahlt, möglicherweise für Überstunden).

Es gibt aber eine Ausnahme

Ich bin der festen Überzeugung, dass die Akzeptanz des automatisierten Testmodells von der "Menschlichkeit" der durchgeführten Tests abhängt. Wenn Sie ein Webmodul mit einem Front-End testen, ist es wahrscheinlicher, dass Sie trotz Tools wie Selen das Formular selbst ausfüllen, das Ergebnis sehen und an Determinismus glauben. Sie werden vergessen, Tests später erneut auszuführen, oder Sie sind einfach zu faul, um alte Tests erneut durchzuführen, und aus diesem Grund werden Fehler manchmal später entdeckt. Um dies zu nutzen, haben sich eine starke Modularisierung des Codes und strenge Regeln zur "Änderung des alten Codes" in einem Bankumfeld als akzeptabel erwiesen (in meiner persönlichen Arbeitserfahrung).

Wenn der Entwickler mit der Entwicklung eines hochautomatisierten Datenmoduls mit hohem Datenvolumen beauftragt ist, wird er mit größerer Wahrscheinlichkeit gründliche Komponententests schreiben und diese an die Teststapel senden. Dies liegt daran, dass das Befüllen einer großen XML-Nutzlast mit Daten, die aus einer externen Datenquelle (verspottet oder nicht) konvertiert wurden, keine für Menschen anfällige Aufgabe ist. Einige Testentwickler werden irgendwann ein kleines und lustiges Frontend für diese spezielle Art von Tests erstellen. Als ich an meiner Masterarbeit arbeitete, arbeitete ich an einem Protokollierungsbus, der über 6000 Syslog-Nachrichten pro Sekunde verarbeitete, und ich musste den Paketverlust und die Beschädigung messen: Ich schrieb natürlich Unit- und Stresstests für fast alle Komponenten, insbesondere den Syslog-Parser.

Um Entwickler anfälliger für Unit-Tests zu machen

Ich glaube, sie müssen dazu gezwungen werden. Wenn Sie ein intelligenter Kunde sind, müssen Ihre Berater bei jeder Qualitätssicherung die gesamte Testsuite ausführen. Wenn Sie ein guter Teamleiter sind, sollten Sie einem intelligenten Entwickler die folgende Aufgabe zuweisen: Erstellen Sie eine interne Testplattform. Das hat nichts mit Antipatter für die innere Effektplattform zu tun, sondern besteht aus einer Reihe von Hilfsklassen, Datenbank-Mocks, Konfigurationen, Parsern, Konvertern und Schweizer Taschenmessern, die Entwicklern helfen, Tests in kürzester Zeit zu erstellen.

Aktuelle Testplattformen wie NUnit sind universell einsetzbar und ermöglichen es Ihnen, allgemeine Behauptungen zu überprüfen. Die korrekte Verwendung von Dependency Injection und projektspezifischen Factorys hilft Entwicklern, weniger Code für Tests zu schreiben und zufriedener zu sein. Ich hatte noch keine Gelegenheit, dies an einem vollständigen Projekt zu experimentieren. Ich kann kein echtes Feedback geben.


1

Automatisiertes Testen ist wie Softwareentwicklung. Leider sind die Leute, die Sie zum Testen anheuern, ursprünglich dazu bestimmt, Testfälle, Pläne, Strategien, den Überprüfungsprozess zu schreiben, Fehler manuell zu testen und zu protokollieren.

Sobald ihnen automatisierte Testaufgaben übertragen wurden, ist ein gewisser Teil der Softwareentwicklung darin enthalten. Der Haken dabei ist, dass automatisierte Tests, unabhängig davon, welche Tools Sie verwenden (und um Himmels willen, diskutieren Sie diesen Punkt nicht), täglich gewartet und aktualisiert werden müssen. Wenn Entwickler den Code ändern,

  • Sie müssen sicherstellen, dass die Tests ausgeführt werden.
  • Sie müssen sicherstellen, dass die Tests nicht entfernt werden, da sie nicht ausgeführt wurden
  • Ihre Testmetriken müssen zeigen, was Sie im letzten Build und in diesem Build ausgeführt haben. So stellen Sie sicher, dass sich die Anzahl Ihrer Testfälle nicht verringert.
  • Testfälle müssen genau wie bei der Entwicklung überprüft werden, um sicherzustellen, dass die Leute nichts falsch machen. Es wird ein Test in zwei aufgeteilt, nur um die Anzahl zu erhöhen.
  • Viel mehr "gesunde" Kommunikation zwischen Entwickler und Test ist wichtig
  • Halten Sie die non-functionalTests getrennt und erwarten Sie nicht, dass sie täglich ausgeführt werden. Es braucht Zeit, um diese auf dem neuesten Stand zu halten. Aber nicht aufgeben, dafür sorgen, dass sie gepflegt werden.

Sie scheitern aus diesen Gründen

  • Ihre Testingenieure sind manuelle Testingenieure ohne analytische Fähigkeiten. Sie kennen den Unterschied zwischen einer ifund einer whileSchleife nicht. Da offen gesagt kein Kurs automatisiertes Testen lehrt, unterrichten sie nur manuelles Testen.
  • Ihre Testingenieure sind zu beschäftigt damit, Ihre Builds manuell zu testen und Fehler zu protokollieren, damit sie den Überblick über automatisierte Tests verlieren
  • Ihre Testmanager kümmern sich nicht um Metriken aus automatisierten Tests, nur weil sie ungültige Daten anzeigen (wenn das Projekt startet), und sie legen keinen Wert auf Aufwand oder Priorität in täglichen Standups und Meetings, um zu betonen, wie wichtig es ist, die Automatisierung zum Laufen zu bringen
  • Sie entscheiden sich für die Automatisierung von Tests für mobile Anwendungen, die eine sehr kurze Haltbarkeit haben. Wenn Sie schreiben, sollten Sie die automatisierte Testsuite stabilisieren, damit sich Ihre Anwendungsanforderungen ändern. Stattdessen sollten Sie sich auf das Testen Ihrer Webservices konzentrieren, auf denen Ihre Anwendung ausgeführt wird
  • Sie verstehen nicht, dass das automatisierte Testteam denselben Meilenstein einhält wie das Entwicklungsteam, das vollständige Feature, den vollständigen Code, die Code-Sperre und das Einfrieren des Codes.
  • Sie unterscheiden nicht zwischen manuellen Testleuten und automatisierten Testleuten.
  • Beide erhalten dasselbe Gehalt und berichten an denselben Manager. Idealerweise sollten sie dem Entwickler-Manager Bericht erstatten und ihre Gehälter sollten denen der Entwicklung entsprechen.
  • Sie denken und glauben, dass junit nicht ausreicht, um automatisierte Tests zu entwickeln :).

Ich arbeite aus Erfahrung für Unternehmen, die automatisierte Tests sehr ernst nehmen und verstehen, dass Entwickler als automatisierte Testingenieure wichtig sind. Und aus meiner Erfahrung heraus für Menschen zu arbeiten, die den Unterschied nicht kennen, verstehen, egal wie viel Sie ihnen erklären.


Bei Unit- und Integrationstests sollten die Entwickler die Tests schreiben, nicht separate "Testingenieure". (Wie in der Frage geschrieben, verwenden die QS, dh die Testingenieure, bereits automatisierte UI-Tests.)
Paŭlo Ebermann,

Realistisch gesehen sollte jeder, der automatisierte Tests schreibt, über Entwicklungsfähigkeiten verfügen.
Siddharth
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.