Trotz der Tatsache, dass es Unit-Testing-Technologien seit 30 Jahren gibt (Kent Beck schrieb 1989 den Artikel „Simple Smalltalk Testing: With Patterns“), besitzen nicht alle Programmierer diese Technologie, und nicht alle Unternehmen haben das automatische Testen zu einem Teil ihrer Unternehmenskultur gemacht. . Trotz der offensichtlichen Vorteile des automatischen Testens ist der Verhaltenswiderstand immer noch recht stark. Wer versucht hat, automatisierte Tests zu implementieren, weiß, dass es immer einen Grund gibt, warum dies nicht möglich ist.
Aus meiner persönlichen Erfahrung mit der Implementierung zuverlässiger Programmiermethoden in meinem Unternehmen, in den von mir konsultierten Unternehmen, der Kommunikation auf Konferenzen und auch aus öffentlich zugänglichen Quellen habe ich typische Einwände und Widerstände formuliert, die die Implementierung einer Kultur des automatischen Testens behindern.
Ich habe alle Einwände in einer Pyramide zuverlässiger Programmierung zusammengefasst, die vier Ebenen umfasst:
- Die Berufskultur (die höchste Ebene, die Grundlage für zuverlässige Programmierung) besteht aus einer Reihe von Normen, ungeschriebenen Regeln und Überzeugungen der Mitarbeiter, die ihn bei seiner Arbeit leiten. Beispiel: "Das Senden von Code, der durch Tests aufgedeckt wurde, an das Repository ist schlecht", "Das Schweigen über gefundene Fehler im Code ist eine Schande".
- Management sind die von der Organisation verabschiedeten Verfahren, Richtlinien, Regeln sowie der Wille (die Entscheidung) der Führungskräfte. Zum Beispiel: „Jede entwickelte Anwendungsfunktion muss einen Überprüfungscode übergeben. Keine Ausnahmen! "
- Methoden sind wissenschaftliche Ansätze, Methoden zur Lösung eines bestimmten Problems. Beispiel: "Wenn die Funktion der Anwendung schwer zu testen ist, müssen Sie die Testbarkeit der Anwendung durch Anwenden der Vorlage" Abhängigkeitsinjektion "verbessern."
- Technologien (die unterste Ebene) sind Programmiersprachen, Bibliotheken, Frameworks und Tools. Zum Beispiel JUnit, Selen, XCTest und so weiter.

Warum ist eine solche Aufteilung notwendig? Weil das Problem einer Ebene durch Methoden derselben Ebene oder durch Methoden einer höheren Ebene gelöst wird. Wenn es beispielsweise für eine Organisation nicht üblich ist, automatische Tests zu schreiben (das Problem der Berufskultur), kann dieses Problem nicht durch eine detaillierte Beschreibung des Testgeschäftsprozesses (Ebene „Management“) oder durch die Installation eines modernen Frameworks (Ebene „Technologie“) gelöst werden. Ich gebe eine Garantie, dass in einer Woche trotz des genehmigten Geschäftsprozesses niemand Tests schreiben wird.
Kulturelle Einwände
„Meine Programme brechen nicht. Ich sehe keine Notwendigkeit zum Testen. "
Ich habe diese Aussage von Anfängern oder übermäßig selbstbewussten Programmierern gehört.
Natürlich kann eine einmal geschriebene Funktion nicht von alleine brechen. Hier ist es jedoch wichtig zu verstehen, dass das Programm im Laufe der Zeit möglicherweise Unterstützung, die Einführung neuer Funktionen oder Ergänzungen bestehender Funktionen benötigt. Die Komplexität der Programme - die Anzahl der Klassen und die Abhängigkeiten zwischen ihnen - ist ziemlich groß, und schließlich tritt früher oder später ein Fehler auf, nachdem eine andere neue Funktion erstellt oder eine vorhandene verbessert wurde. Ein automatischer Test würde eine solche Regression erkennen.
Darüber hinaus ist ein solcher Einwand häufig von unerfahrenen Programmierern zu hören, die kein Testkonzept haben. Beispielsweise werden nur Abstürze als Ausfall betrachtet, keine Funktionsfehler.
Bei einem der von mir durchgeführten Interviews fand folgender Dialog statt:
- Haben Sie die Fähigkeiten zum automatischen Testen?
- Nein, ich habe einfache Programme geschrieben, es gab nichts zu brechen.
- Was ist Ihre Motivation, den Job zu wechseln?
- Ich möchte komplexe Anwendungen schreiben.
Ich weiß sehr gut, wie das endet. Dem Programmierer wird vertraut, dass er ein komplexeres Programm entwickelt, er kennt jedoch die Methoden des automatischen Testens nicht, er kann die Anwendung nicht qualitativ testen und er kann den Umfang des Projekts nicht bewältigen, was zu einer Störung des Projekts, einer Kostenüberschreitung der Entwicklung und einem Reputationsverlust führen wird. Weil ich persönlich Projekte geleitet habe, bei denen ich den Umfang des Projekts nicht bewältigen konnte und es gerade wegen des Fehlens automatischer Tests nicht bestanden habe.
Widerwillen, Verantwortung für die Qualität des Codes zu übernehmen, für Tests.
Automatisierte Tests sind die einzige Quelle für betriebliche und objektive Informationen über die wahre Qualität eines Softwareprodukts. Mit anderen Worten, der Programmierer hat immer einen Vorgesetzten hinter seinem Rücken, der dem Management jederzeit berichten kann, wie gut der Programmierer seine Arbeit macht. Mit automatisierten Tests können Sie die Produktivität der Arbeit nicht mit geschlossenen Tickets im Jira verknüpfen, sondern mit der tatsächlichen Qualität des Softwareprodukts. Und hier müssen Sie bereits darüber nachdenken, wie Sie zuverlässig schreiben können, damit bei jeder nächsten Änderung des Codes vorhandene Funktionen nicht beschädigt werden. Damit jede neue Funktion nicht nur im Skript funktioniert, wenn alles in Ordnung ist, sondern auch Fehler korrekt verarbeitet.
Verantwortung ist die freiwillige Verpflichtung, ein positives Arbeitsergebnis sicherzustellen. Der Mitarbeiter übernimmt diese Verpflichtung aufgrund seines Charakters und seiner Ausbildung. Leider ist aufgrund der kulturellen und beruflichen Krise nicht jeder Programmierer bereit, solche Verpflichtungen zu übernehmen.
"Schreiben Sie jetzt ohne Fehler"
Menschen, die mit der Funktionsweise der Softwareentwicklung nicht sehr vertraut sind, stehen Entwicklern, die Fehler erwähnen, möglicherweise negativ gegenüber.
- Lassen Sie uns die Anwendung mit automatischen Tests abdecken.
- Warum?
- Um sicherzustellen, dass alles richtig funktioniert und keine Fehler vorliegen.
- Schreiben Sie mit Fehlern? Haben Sie geringe Qualifikationen? Schreiben Sie sofort ohne Fehler.
"Ja, aber jeder macht Fehler ..."
- Aber die Firma XYZ sagte zu einem Freund, dass sie Top-Programmierer haben, die fehlerfrei schreiben!
Daher ist es schwierig, die Entwicklung von Tests an Kunden zu „verkaufen“, die technisch nicht versiert sind. Infolgedessen ist das Management gezwungen, ein Projekt ohne automatische Tests zu entwickeln, was zu bekannten Problemen führt.
Einwände des Managements
„Bei Tests ist das Schreiben eines Programms doppelt so lang. Wir werden die Fristen nicht einhalten. “
Diese These erscheint auf den ersten Blick fair. Es ist wirklich notwendig, Programmiererzeit damit zu verbringen, Tests zu schreiben. Programmierer und Management berücksichtigen jedoch nicht, dass die gesamte Produktentwicklungszeit nicht nur die Programmierung, sondern auch das Debuggen und den Support sowie die enormen Kosten für manuelle Regressionstests nach Korrekturen umfasst.
Automatisierte Tests haben mehrere Funktionen:
- Überprüfen .
1.1. Tests stellen sicher, dass das Testobjekt ordnungsgemäß funktioniert.
1.2. Tests überprüfen die Qualität der Arbeit des Programmierers: ob die Aufgabe gelöst ist, ob es irgendwelche Nebenwirkungen in Form von Regressionen gibt. - Diagnose . Diagnosetests können die Zeit für die Suche nach einem Defekt erheblich verkürzen. Mit Tests können Sie den Ort des Fehlers genau auf die Klasse und Methode und manchmal auf die Codezeile genau bestimmen.
- Automatisieren . Mit Tests können Sie das Testobjekt schnell und einfach im gewünschten Status zum Debuggen eingeben.
- Dokumentieren .
4.1. Abnahmetests erfassen die Anforderungen des Kunden an das zu entwickelnde Produkt.
4.2. Tests zeigen Beispiele für die Verwendung der entwickelten Komponente, wodurch der Zeitaufwand für das Studium der Arbeit des Systems durch einen anderen Programmierer verringert wird.
In einer der von mir konsultierten Organisationen widersetzte sich der Manager der Einführung einer Kultur des automatischen Testens:
- Aber Tests schon lange schreiben! Wir werden keine Fristen einhalten!
- Haben Sie Fehler, nach denen Sie schon sehr lange gesucht und diese korrigiert haben?
- Ja, es gibt einige.
- Was ist der schwierigste Fall?
- Wir haben 80 Stunden lang nach einem Fehler gesucht.
- 80 Stunden sind zwei Wochen Arbeit des Programmierers. Wenn Sie sogar eine ganze Woche lang die Automatisierung testen würden, würden Sie Monate bei der Diagnose und beim Debuggen Ihrer Anwendung sparen!
Unsere Organisation hat das Postulat: "Mit Tests ist das Schreiben eines Programms doppelt so schnell!" und dieses Postulat wird nicht diskutiert. Es wird nur der Koeffizient 2 diskutiert - manchmal gibt es 3 und 4. Und einige Projekte können ohne kompetente automatische Tests einfach nicht abgeschlossen werden (siehe das überforderte Projekt).
"Wir haben bereits eine manuelle Testabteilung, lassen Sie sie testen."
Auf den ersten Blick erscheint die Trennung von Spezialisierungen in Test und Programmierung logisch.
Aber schauen wir uns die Nachteile des manuellen Testens an:
- Es ist sehr teuer.
- Es dauert sehr lange. Beispiel: Das Testskript für den Tester der mobilen Anwendung „Online Cinema“ dauert 40 Stunden. Und das nur für eine Plattform! Wenn Sie die Anwendung auf iPhone, iPad, Apple TV, Android und Fire TV testen müssen, müssen Sie 40 × 6 = 240 Stunden Arbeitszeit aufwenden. Dies sind anderthalb Monate, was für kurze Entwicklungszyklen nicht akzeptabel ist.
- Manuelle Tests unterliegen häufigen menschlichen Fehlern - sie liefern kein objektives und wahres Ergebnis.
Darüber hinaus können einige Arten von Tests nicht innerhalb einer angemessenen Zeit durchgeführt werden, da die Anzahl der Kombinationen von Formaten und verschiedenen Testskripten sehr groß ist. Zum Beispiel:
- Funktion zum Importieren von CSV-Dateien.
- Parser für Textdokumente.
- Finanzinstrumente.
Einwände auf Methodenebene
Ignoranz automatischer Testmethoden.
Aufgrund der Bildungskrise gibt es an den Universitäten keine Disziplinen für automatische Tests. Es gibt nur sehr wenige solcher Kurse an kommerziellen IT-Schulen. Und die bestehenden Kurse sind oberflächlich und von schlechter Qualität. Daher habe ich unter Programmierern oft einen Stupor erlebt: Sie wissen nicht, wie man nicht triviale Anwendungen testet (schwieriger als 2 + 2 = 4).
In der Tat ist die Wissenschaft des Testens ziemlich umfangreich. Zum Beispiel wird nicht jeder Programmierer die Fragen sofort beantworten: a) Was ist Testbarkeit? b) Was ist Kontrollierbarkeit und Beobachtbarkeit? c) Welche Entwurfsmuster verbessern die Testbarkeit der Anwendung? Usw.
Programmierer wissen nicht, was sie schreiben, wie es aussieht, welche Funktionen und Schnittstellen es geben wird.
Es ist sehr schwierig zu testen, was nicht klar ist, wie es aussieht. Mit anderen Worten, ohne die vordefinierten Anforderungen für die Anwendung kann der Programmierer nicht verstehen, was von ihm erwartet wird.
Die Besonderheit einiger Projekte besteht darin, dass sie unter Verwendung der Minimum Viable Product-Technologie entwickelt werden, die mit anderen Worten wie folgt beschrieben werden kann: „Lassen Sie uns zumindest etwas für die minimale Zeit und das minimale Budget tun“, und der Programmierer wird vom Kunden oder Management als Analyst, Designer, Architekt betrachtet. Programmierer und Tester in einer Flasche. Bei diesem Ansatz wird die formale Phase des Entwurfs eines Softwaresystems ausgeschlossen: die Definition von Geschäftslogik, Domäne, Komponentenschnittstellen sowie deren interne Organisation ihrer Beziehung zwischen ihnen. Es gibt keine formalisierte Architektur, keine Schnittstellen, keine vorgeschriebenen Geschäftsprozesse - es ist nicht klar, was getestet werden soll, über welche Schnittstellen und was das erwartete Ergebnis ist.
Unangemessener Code.
Testbarkeit ist eine Projekteigenschaft, die angibt, wie einfach sie getestet werden kann. Die Testeignung wird durch zwei weitere Eigenschaften bestimmt: Kontrollierbarkeit und Beobachtbarkeit. Verwaltbarkeit - Eine Eigenschaft, die bestimmt, wie einfach es ist, eine Anwendung zum Testen in den gewünschten Zustand zu versetzen (Voraussetzungen erfüllen). Beobachtbarkeit - Wie einfach es ist, den Zustand nach dem Test zu betrachten, vergleichen Sie ihn mit dem erwarteten.
Beispielsweise ist es sehr schwierig, die Zwei-Faktor-Authentifizierung mithilfe von SMS automatisch zu testen, da die Funktion zum Empfangen von SMS außerhalb des Bereichs der automatisierten Testumgebung liegt. Ein solches System ist ungeeignet.
Angesichts eines ungeeigneten Systems gibt der Programmierer auf und vermeidet das Testen eines solchen Systems.
Vorbereitung der Testdaten.
Einer der nicht offensichtlichen Widerstände ist die Erstellung von Testdaten und Standards. Beispiel: Der Anfangszustand der Datenbank, für die Tests durchgeführt werden. Die Erstellung von Testdaten kann viel Zeit und Routinearbeit erfordern, daher wird diese Arbeit von Programmierern als undankbar und uninteressant angesehen.
Lösung:
- Entwicklung von Referenzwerten und Beispielen in der Phase der Entwicklung von Abnahmetests - sie werden auch dazu beitragen, Konflikte mit dem Kunden in der Phase der Abnahme der Arbeit zu lösen.
- Entwicklung von Referenzwerten in der Phase des Systemdesigns. Beispielsweise erleichtern Standard-HTTP-Anforderungen und -Antworten die Integration von Client und Server.
- Entwicklung spezieller Verfahren zum Zusammenstellen von Datenbanken, bei denen der erforderliche Status der Datenbank automatisch und nicht manuell erstellt wird
- Verwendung der Vorlage Objektmutter [Fowler, Schuh, Peter und Stephanie Punke. "Vereinfachen der Erstellung von Testobjekten in XP." XP-Universum. 2003], mit dessen Hilfe Objekte im erforderlichen Zustand einfach zugeordnet und initialisiert werden können.
Testdienst.
Während der Entwicklung eines Projekts können sich die Anforderungen (Klärung, Änderung) ändern. Oder es kann zu internem Refactoring kommen, was zu einer Änderung der Klassenschnittstellen führt. Mit der Änderung der Anforderungen ändern sich auch die Akzeptanzkriterien einer bestimmten Funktion und damit auch die Tests. Irgendwann kann der Programmierer die Wartung der Tests verweigern, dh sie auf dem neuesten Stand halten.
Lösung:
- Verwenden der Vorlage "Adapter", um die Logik des Tests von der zu testenden Schnittstelle zu entkoppeln;
- Verwendung von hochrangigen Tests (Gurke, Gurke, gegeben-wann-dann);
- Siehe Lösung gegen Widerstand „Vorbereitung der Testdaten“.
Fazit
Es besteht kein Zweifel, dass Software zuverlässig sein muss: die Erwartungen der Kunden übertreffen. Automatisierte Tests sind nicht die einzige, sondern wichtige Komponente bei der Entwicklung zuverlässiger Software.
Ich formulierte typische Einwände und Hindernisse für die Implementierung automatischer Tests, auf die ich persönlich in meiner Organisation sowie in den von mir konsultierten Organisationen gestoßen bin.
Der Artikel beschreibt nur Probleme und geht kaum auf Lösungswege ein. Im Allgemeinen scheint mir die Strategie zur Lösung dieser Probleme folgendermaßen zu sein:
- Bildung und Förderung einer neuen Kultur des IT-Designs, die Zuverlässigkeit, Stolz und persönliche Verantwortung für das Ergebnis bedeutet.
- Entwicklung neuer hoher Standards für Codetests.
- Entwicklung und Durchführung von Schulungen.
- Die Einführung von Motivation in die Karriere von Programmierern und Managern, verbunden mit der Qualität der zu entwickelnden Softwareprodukte sowie mit den Fähigkeiten des automatischen Testens.
Das Wichtigste, was ich verstanden habe, ist, dass die Probleme auf verschiedenen Ebenen liegen: technologisch, methodisch, verwaltungstechnisch und kulturell. Und sie müssen auf angemessenen Ebenen angegangen werden. Es ist sehr schwierig, automatisierte Tests zu implementieren, wenn der Programmierer nicht in testgeeigneten Entwurfsmethoden geschult ist oder wenn das Management keine Kultur zuverlässiger Programmierung in der Organisation unterstützt.
Ich bin dankbar für Beispiele aus Ihrer Praxis, wie einfach oder wie schwierig es war, automatisierte Tests in Ihrem Unternehmen durchzuführen. Welche Probleme hatten Sie? Wie hast du sie gelöst?