Die Kernidee von Test-Driven Development (TDD) besteht darin, Tests vor dem Schreiben von Funktionscode zu schreiben und dann nur so wenig Code zu schreiben, wie für den Test erforderlich ist. Es mag seltsam klingen, sich auf diese Weise zu entwickeln, aber es ist tatsächlich sehr nützlich, da die Testbasis als Teilspezifikation des Hauptcodes dient.
Unter dieser einfachen Voraussetzung gibt es jedoch eine erstaunliche Menge an Terminologie und Techniken. In diesem Artikel fasse ich die wichtigsten Begriffe und Schlagworte zusammen, die Sie vielleicht hören, und definiere sie.
Die Test-First-Programmierung ermöglicht hochrangige Funktionstests.
Die höchste Teststufe belegt, dass die Software die Anforderungen des Kunden erfüllt. Abnahmetests werden im Allgemeinen in Umgebungen durchgeführt, die so nah wie möglich an der Produktion sind. Siehe Funktionsprüfung und Systemprüfung.
Zusicherungen sind Anweisungen, die eine tatsächliche Überprüfung der Software-Ausgabe durchführen. Im Allgemeinen wird eine einzelne Funktion aufgerufen behaupten
reicht aus, um jeden Scheck auszudrücken. In der Praxis haben Testbibliotheken oft viele Assert-Funktionen, um bestimmte Anforderungen zu erfüllen (z. B. assertFalse
, assertEqual
und mehr), um eine bessere Analyse und eine freundlichere Ausgabe zu bieten.
Eine Testmethode, die Test beinhaltet, verdoppelt die Software und gibt an, dass sie korrekte Methoden in der richtigen Reihenfolge aufruft. Siehe Beispiel für ein Beispiel. Siehe auch Zustandstest.
Eine Teilmenge von TDD, die durch die Notwendigkeit klarerer Kommunikation und ordnungsgemäßer Dokumentation getrieben wird. BDD ist vielleicht die jüngste Entwicklung in TDD.
Seine Kernidee ist es, verwirrende und auf Entwickler bezogene Terminologie zu ersetzen (Tests, Suiten, Behauptungen etc) mit allgegenwärtige Sprache dass alle beteiligten Stakeholder (einschließlich nicht-technischer Mitarbeiter und möglicherweise auch Kunden) verstehen können.
Siehe User Story.
Ein allgemeiner Testgrundsatz, bei dem die Person, die Tests schreibt, die Interna der Software nicht kennt oder vermeidet, und stattdessen die öffentliche Schnittstelle der Software streng nach ihrer Schnittstelle oder Spezifikation testet. Siehe White-Box-Tests.
Eine Strategie zum Schreiben von Tests, um einzelne Fehler und andere ähnliche Fehler zu erkennen. Um Grenzwerttests durchzuführen, testen Sie die Eingaben an bestimmten möglicherweise problematischen Grenzen. Bei ganzen Zahlen kann dies sein 0
, -1
, MIN_INT
, MAX_INT
und andere ähnliche Werte.
Zusicherungen sind Anweisungen, die eine tatsächliche Überprüfung der Software-Ausgabe durchführen.
Ein Dummy ist eine Art Test-Double, der niemals von der eigentlichen Software verwendet wird, sondern nur zum Testen der erforderlichen Parameter verwendet wird.
Fakes sind Test-Doubles, die die erforderliche Funktionalität auf eine Weise implementieren, die für das Testen nützlich ist, sie jedoch auch von der Verwendung in der Produktionsumgebung ausschließt. Beispielsweise kann eine Schlüsselwertdatenbank, in der alle Werte im Speicher gespeichert werden und nach jeder Ausführung verloren gehen, möglicherweise dazu führen, dass Tests schneller ausgeführt werden. Die Tendenz, Daten zu zerstören, würde sie jedoch nicht in der Produktion verwenden.
Eine bestimmte Umgebung, die eingerichtet werden muss, bevor ein Test ausgeführt werden kann. Es besteht im Allgemeinen aus dem Einrichten aller Test-Doubles und anderer Abhängigkeiten für die zu testende Software: Zum Beispiel das Einfügen vordefinierter Daten in eine gefälschte Datenbank, das Einrichten einer bestimmten Verzeichnisstruktur im gefälschten Dateisystem, das Einrichten von Eigenschaften für die Abhängigkeiten der getesteten Software.
Eine Testaktivität auf hohem Niveau, mit der sichergestellt wird, dass alle Geschäftsanforderungen des Produkts erfüllt werden. Funktionstests umfassen im Allgemeinen die Verwendung von User Storys, um sich auf ein höheres Anforderungsniveau zu konzentrieren, um möglichst viele Nutzungsszenarien abzudecken. Siehe Abnahmetests und Systemtests. Zum Beispiel:
# In diesem Beispiel überprüfen wir, ob die About-Seite der Website wie erwartet funktioniert. Öffnen Sie "example.com". "ClickOn". Über uns. "AssertThereIs" "Wir sind ein kleines Beispielunternehmen".
Ein umgangssprachlicher Ausdruck für das Bestehen von Tests oder manchmal auch für einen bestimmten Test. Rot sehen.
Eine Testaktivität auf mittlerer Ebene, bei der sichergestellt wird, dass bestimmte Module ordnungsgemäß zusammenarbeiten. Integrationstests sind wie Komponententests ohne Verwendung von Testverdopplungen für eine bestimmte Teilmenge von Abhängigkeiten, wobei im Wesentlichen die Interaktionen zwischen der Software und ihren Abhängigkeiten getestet werden. Beispiel:
# In diesem Beispiel überprüfen wir, ob der neu registrierte Benutzer, # der von einem anderen Benutzer verwiesen wurde, vor Ort eine "Freundschaft" erstellt. # Hier überprüfen wir die Interaktion zwischen dem Formular-Controller, der Datenbank und einem aktiven Datensatz des Benutzers. Db = new Fake Db u1 = db.createUser (name = 'john') RegistrationForm (db, name = "kate", referenziert = "john") ") .save () - Assert (u1.hatFriend ('kate'))
Ein Typ von Testdoppel, der für einen bestimmten Test oder Testfall erstellt wurde. Es wird erwartet, dass es eine bestimmte Anzahl von Malen aufgerufen wird, und gibt eine vordefinierte Antwort. Am Ende des Tests gibt ein Mock einen Fehler aus, wenn er nicht so oft aufgerufen wurde wie erwartet. Ein Modell mit strengen Erwartungen ist Teil des Durchsetzungsrahmens. Beispiel:
# In diesem Beispiel verwenden wir eine Scheindatenbank, um zu überprüfen, ob das Formular # die Datenbank zum Speichern des neuen Benutzers verwendet. # Wenn die Datenbank am Ende des Tests nicht aufgerufen wurde, wird # der Mock selbst einen Assertionsfehler auslösen. db = new Mock Db db.expect ('save'). once (). mit (name = 'john') RegistrationForm (db, name = "john"). save ()
Eine Möglichkeit, das Verhalten vorhandener Objekte und Klassen in einer Programmiersprache zu erweitern und zu ändern. Das Affen-Patching kann als Alternative zur Abhängigkeitsinjektion und Testverdoppelung verwendet werden, indem vorhandene Funktionen, die von der zu testenden Software aufgerufen werden, direkt geändert werden (und nach dem Test zurückgesetzt werden)..
# In diesem Beispiel ersetzen wir die Standard-Bibliotheksfunktion #, um zu verhindern, dass der Test ein reales Dateisystem verwendet. Filesystem.listdir = f (name) -> ['.', '…', 'Foo', 'bar']; assertEqual (MyFileSearch ('foo'). count (), 1)
Ein umgangssprachlicher Ausdruck für eine fehlgeschlagene Sammlung von Tests oder manchmal für einen bestimmten fehlgeschlagenen Test. Siehe grün.
Der Prozess zum Verbessern der Implementierungsdetails von Code, ohne die Funktionalität zu ändern.
Refactoring ohne Tests ist ein sehr spröder Prozess, da der Entwickler, der das Refactoring durchführt, nie sicher sein kann, dass seine Verbesserungen einige Teile der Funktionalität nicht beeinträchtigen.
Wenn der Code mithilfe von testgetriebener Entwicklung geschrieben wurde, kann der Entwickler sicher sein, dass sein Refactoring erfolgreich war, sobald alle Tests bestanden wurden, da alle erforderlichen Funktionen des Codes noch korrekt sind.
Ein Softwarefehler, der in einem bestimmten Feature nach einem Ereignis auftritt (normalerweise eine Änderung des Codes)..
Szenariotest
Siehe Funktionsprüfung.
Ein Prozess der Vorbereitung einer Vorrichtung. Siehe Abriß. Beispiel:
# In diesem Beispiel bereiten wir eine gefälschte Datenbank mit einigen falschen Werten vor #, die wir über mehrere Tests hinweg benötigen werden. Db = neue falsche Datenbank db.createUser (name = 'john') db.createUser (name = 'kate') db.createFriendship ( 'john', 'kate')
Eine Form von Unit-Tests, wenn der Testcode einen Test bereitstellt, verdoppelt sich und stellt fest, dass der Status dieser Doubles korrekt geändert wurde. Siehe Verhaltenstest.
# In diesem Beispiel wird, wie in einem Beispiel für Scheinobjekte, # überprüft, ob das Formular die Datenbank zum Speichern des neuen Benutzers verwendet. # Dieses Mal prüfen wir den Status anstelle des Verhaltens db = new Fake Db RegistrationForm (db, name = "john"). Save () assertInList ('john', db.listUsers ())
Fälschungen sind Testverdopplungen, die niemals von der eigentlichen Software verwendet werden.
Eine Art von Test-Double, das mit vordefinierten Antworten auf die getestete Software antworten kann. Im Gegensatz zu Mocks prüfen Stubs jedoch normalerweise nicht, ob sie richtig aufgerufen wurden, sondern stellen lediglich sicher, dass die Software ihre Abhängigkeiten aufruft.
Eine Testaktivität auf hohem Niveau, wenn die gesamte Software von oben nach unten getestet wird. Dies umfasst die Funktionsprüfung sowie das Prüfen anderer Merkmale (wie Leistung und Stabilität)..
Eine Abkürzung für getestete Software. Wird verwendet, um die getestete Software von ihren Abhängigkeiten zu unterscheiden.
Ein Reinigungsprozess für eine Vorrichtung. In nicht erfassten Sprachen wird diese Funktionalität meist automatisch ausgeführt. Siehe Setup.
Die kleinstmögliche Prüfung auf Richtigkeit. Ein einzelner Test für ein Webformular könnte beispielsweise eine Prüfung sein, bei der das Formular bei einer ungültigen E-Mail-Adresse den Benutzer warnt und eine Korrektur vorschlägt. Siehe Testfall.
Eine nach einem Attribut gruppierte Sammlung von Tests. Ein Testfall für ein Webformular könnte beispielsweise eine Sammlung von Tests sein, die das Verhalten des Formulars auf verschiedene gültige und ungültige Eingaben überprüfen.
Funktion t1: assertNoError (RegistrationForm (Name = 'john', Passwort = "Pferdebatterieheftung korrekt"). save ()) Funktion t2: assertError (MissingPassword, RegistrationForm (name = 'john'). save ()) Funktion t3: assertError (StupidPassword, RegistrationForm (name = 'john', password = "password"). save ())
Benutzergeschichten werden normalerweise in menschlichen Sprachen definiert, um sich stattdessen auf die Benutzererfahrung zu konzentrieren.
Jede Art von Metrik, die versucht, die Wahrscheinlichkeit eines wichtigen Verhaltens des SUT zu schätzen, wird immer noch nicht durch Tests abgedeckt. Die beliebtesten Techniken umfassen verschiedene Arten von Codeabdeckung: Techniken, die sicherstellen, dass alle möglichen Codeanweisungen (oder Funktionen oder logischen Verzweigungen im Code) während des Tests ausgeführt wurden.
Ein Prozess der TDD-Entwicklung. Da die TDD-Entwicklung mit dem Schreiben einiger Tests beginnt, ist klar, dass die Testsuite rot beginnt. Sobald der Entwickler alle neu getesteten Funktionen implementiert, werden die Tests grün. Jetzt kann der Entwickler seine Implementierung sicher umgestalten, ohne dass neue Fehler auftreten, da er eine Test-Suite hat, auf die er sich verlassen kann. Sobald das Refactoring abgeschlossen ist, kann der Entwickler den Zyklus erneut starten, indem er weitere Tests für weitere neue Funktionen schreibt. Und so kam es dass der Rot-Grün-Refaktor-Testzyklus.
Test doppelt
Test-Doubles sind Objekte, die der Testcode erstellt und an das SUT weiterleitet, um echte Abhängigkeiten zu ersetzen. Zum Beispiel sollten Unit-Tests sehr schnell sein und nur eine bestimmte Software testen.
Aus diesen Gründen werden seine Abhängigkeiten, z. B. eine Datenbank- oder Dateisysteminteraktionsbibliothek, normalerweise durch Objekte ersetzt, die im Arbeitsspeicher agieren, anstatt mit einer echten Datenbank oder einem Dateisystem zu kommunizieren.
Es gibt vier Hauptkategorien von Test-Doubles: Dummys, Fakes, Stubs und Mocks.
Eine Sammlung von Testfällen, die einen großen Teil der Software testen. Alternativ alle Testfälle für eine bestimmte Software.
White-Box-Tests ermöglichen eine tiefere Analyse möglicher Probleme im Code.
Test-First-Programmierung ist ein etwas breiterer Begriff für testgetriebene Entwicklung. Während TDD eine enge Kopplung zwischen Schreibtests (normalerweise Komponententests) und Schreiben des Codes fördert, ermöglicht die Test-First-Programmierung stattdessen Funktionstests auf hohem Niveau. Der Unterschied in der allgemeinen Verwendung wird jedoch selten bemerkt, und in zwei Fällen werden die Ausdrücke normalerweise austauschbar verwendet.
Die Testmethode der untersten Ebene besteht aus Testfällen für kleinstmögliche Codeeinheiten. Ein einzelner Unit-Test prüft normalerweise nur ein bestimmtes kleines Verhalten, und ein Unit-Testfall deckt normalerweise alle Funktionen einer bestimmten Funktion oder Klasse ab.
Eine einzige Beschreibung einer bestimmten Gruppe von Personen, die eine bestimmte Aufgabe mit dem SUT ausführen möchten, um ein bestimmtes Ziel zu erreichen. User Storys werden in der Regel in menschlichen Sprachen definiert und verwenden einfache, benutzerorientierte Begriffe, um zu vermeiden, dass Implementierungsdetails berücksichtigt werden, und sich stattdessen auf die Benutzererfahrung zu konzentrieren. Zum Beispiel:
Als Benutzer möchte ich meine Freunde auf dieser Website anhand meines Adressbuchs finden können, anstatt sie einzeln zu suchen, denn das spart mir viel Zeit.
White-Box-Test ist eine Testmethode, wenn eine Person, die den Test durchführt, die internen Komponenten des SUT kennt oder lesen kann. Im Gegensatz zu den allgemeineren Black-Box-Tests ermöglichen White-Box-Tests eine tiefere Analyse möglicher Probleme im Code.
Beispielsweise kann ein bestimmter Grenzwert nicht nur aufgrund der Spezifikation der Software aussehen, er kann jedoch aus der Implementierung ersichtlich sein.
Darüber hinaus sind alle Test-Coverage-Techniken normalerweise per Definition Teil des White-Box-Tests.