Test-Driven development

Test-Driven development

Als testgetriebene Entwicklung (auch testgesteuerte Programmierung, engl. test first development oder test-driven development (TDD), manchmal auch scherzhaft Extreme Testing) ist eine Methode, die häufig bei der agilen Entwicklung von Computerprogrammen eingesetzt wird. Bei der testgetriebenen Entwicklung erstellt der Programmierer Software-Tests konsequent vor den zu testenden Komponenten. Die dazu erstellten Unit-Tests sind Grey-Box-Tests statt klassischer White-Box-Tests.

Inhaltsverzeichnis

Gründe für die Einführung einer testgetriebenen Entwicklung

Nach klassischer Vorgehensweise, beispielsweise nach dem Wasserfall- oder dem V-Modell, werden Tests parallel zum und unabhängig vom testenden System entwickelt oder sogar nach ihm. Dies führt oft dazu, dass nicht die gewünschte und erforderliche Testabdeckung erzielt wird. Mögliche Gründe dafür sind unter anderem:

  • Fehlende oder mangelnde Testbarkeit des Systems (monolithisch, Nutzung von Fremdkomponenten, …).
  • Verbot der Investition in nicht-funktionale Programmteile seitens der Unternehmensführung. („Arbeit, von der man später im Programm nichts sieht, ist vergeudet.“)
  • Erstellung von Tests unter Zeitdruck.
  • Nachlässigkeit und mangelnde Disziplin der Programmierer bei der Testerstellung.

Ein weiterer Nachteil klassischer White-Box-Tests ist, dass der Entwickler das zu testende System und seine Eigenheiten selbst kennt und dadurch aus Betriebsblindheit unversehens "um Fehler herum" testet.

Die Methode der testgetriebenen Entwicklung versucht den Gründen für eine nicht ausreichende Testabdeckung und einigen Nachteilen der White-Box-Tests entgegenzuwirken.

Vorgehensweise

Bei der testgetriebenen Entwicklung ist zu unterscheiden zwischen dem Testen im Kleinen (Unit-Tests) und dem Testen im Großen (Systemtests, Akzeptanztests), wobei Beck's Methode auf Unit-Tests ausgelegt ist.

Testgetriebene Entwicklung mit Unit-Tests

Unit-Tests und mit ihnen getestete Units werden stets parallel entwickelt. Die eigentliche Programmierung erfolgt in kleinen und wiederholten Mikroiterationen. Eine solche Iteration, die nur wenige Minuten dauern sollte, hat drei Hauptteile:

  1. Schreibe Tests für das erwünschte fehlerfreie Verhalten, für schon bekannte Fehlschläge oder für das nächste Bröckelchen Funktionalität, das neu implementiert werden soll. Diese Tests werden vom bestehenden Programmcode erst einmal nicht erfüllt bzw. es gibt diesen noch gar nicht.
  2. Ändere/schreibe den Programmcode mit möglichst wenig Aufwand, bis nach dem anschließend angestoßenen Testdurchlauf alle Tests bestanden werden.
  3. Räume dann im Code auf (Refactoring): Entferne Wiederholungen (Code-Duplizierung), abstrahiere wo nötig, richte ihn nach den verbindlichen Kodekonventionen aus etc. Natürlich wieder mit abschließendem Testen. Ziel des Aufräumens ist es, den Code schlicht und verständlich zu machen.

Diese drei Schritte werden so lange wiederholt, bis die inzwischen geschaffenen Tests alle bestanden werden und dem Entwickler keine sinnvollen weiteren mehr einfallen, die vielleicht noch scheitern könnten. Die so behandelte programmtechnische Einheit (Unit) wird dann als (vorerst) fertig angesehen.

Die konsequente Befolgung dieser Vorgehensweise läuft auf evolutionären Entwurf hinaus, weil die ständige Änderung die Weiterentwicklung eines Systems in den Vordergrund rückt.

Da der einzelne Unit-Test sowohl Züge eines White-Box-Tests als auch eines Black-Box-Tests aufweist, bezeichnet man ihn auch als Grey-Box-Test.

Testgetriebene Entwicklung mit Systemtests

Systemtests werden immer vor dem System selbst entwickelt oder doch wenigstens spezifiziert. Aufgabe der Systementwicklung ist bei testgetriebener Entwicklung nicht mehr, wie klassisch, schriftlich formulierte Anforderungen zu erfüllen, sondern spezifizierte Systemtests zu bestehen.

Gemeinsamkeiten zwischen Testgetriebener Entwicklung mit Systemtests und Unit-Tests

Bei beiden Arten von Tests wird eine möglichst vollständige Testautomatisierung angestrebt. Für testgetriebene Entwicklung müssen alle Tests einfach („per Knopfdruck“) und möglichst schnell ausgeführt werden können. Für Unit-Tests bedeutet das eine Dauer von wenigen Sekunden, für Systemtests von maximal einigen Minuten, bzw nur in Ausnahmen länger.

Die großen Vorzüge der testgetriebenen Methodik gegenüber der klassischen sind:

  • Man hat eine triviale Metrik für die Erfüllung der Anforderungen: die Tests werden bestanden oder nicht.
  • Das Refaktorisieren, also das Aufräumen im Code, führt zu weniger Fehlern; weil man dabei in kleinen Schritten vorgeht und stets entlang bestandener Tests, entstehen dabei wenige neue, und sie sind besser lokalisierbar.
  • Weil einfach und ohne großen Zeitaufwand getestet werden kann, arbeiten die Programmierer die meiste Zeit an einem korrekten System und also mit Zutrauen und konzentriert auf die aktuelle Teilaufgabe hin. (Keine „Durchquerung der Wüste“, kein „Alles hängt mit allem zusammen“)
  • Der Bestand an Unit-Tests dokumentiert das System zugleich. Man erzeugt nämlich zugleich eine „ausführbare Spezifikation“ – was das Softwaresystem leisten soll, liegt in Form sowohl lesbarer wie auch jederzeit lauffähiger Tests vor.

Einsatzgebiete

Testgetriebene Entwicklung ist wesentlicher Bestandteil des Extreme Programming (XP) und anderer agiler Methoden. Auch außerhalb dieser ist sie anzutreffen, häufig in Verbindung mit der Paarprogrammierung .

Werkzeuge

Die testgetriebene Entwicklung braucht vordinglich

  • ein Werkzeug zur Build-Automatisierung wie etwa CruiseControl
  • einen Rahmen und ein Werkzeug zu Testentwicklung und -automatisierung,

damit die Iterationen schnell und unkompliziert durchlaufen werden können.

Bei der Java-Entwicklung kommen dafür meist Ant und JUnit zum Einsatz. Für die meisten anderen Programmiersprachen existieren ähnliche Werkzeuge, wie z. B. für PHP PHPUnit.

Für komplexe Systeme müssen mehrere Teilkomponenten unabhängig voneinander entwickelt werden und es finden dazu auch noch Fremdkomponenten Verwendung, etwa ein Datenbanksystem zwecks persistenter Datenhaltung. Die korrekte Zusammenarbeit und Funktion der Komponenten im System muss dann auch getestet werden. Um nun die Einzelkomponenten dabei separat testen zu können, die doch aber zu ihrer korrekten Funktion wesentlich von anderen Komponenten abhängen, verwendet man Mock-Objekte als deren Stellvertreter. Die Mock-Objekte ersetzen und simulieren im Test die benötigten anderen Komponenten in einer Weise, die der Tester ihnen einprogrammiert.

Ein Werkzeug für Akzeptanztests und Systemtests ist beispielsweise Framework for Integrated Test. Eine beliebte FIT-Variante ist Fitnesse, ein Wiki-Server mit integrierter Testerstellungs- und Testausführungsumgebung.

Kritik

Konsequenz ist nötig

Auch die Methode der testgetriebenen Entwicklung kann falsch eingesetzt werden und dann scheitern. Programmierern, die noch keine Erfahrung dabei besitzen, erscheint sie manchmal schwierig oder gar unmöglich. Sie fragen sich, wie man etwas testen soll, das doch noch gar nicht vorhanden ist. Auswirkung kann sein, dass sie die Prinzipien dieser Methode vernachlässigen, was insbesondere bei agilen Methoden wie dem Extreme Programming Schwierigkeiten beim Entwicklungsprozess oder sogar dessen Zusammenbruch zur Folge haben kann. Ohne ausreichende Unit-Tests wird keine ausreichende Testabdeckung für das Refactoring und die gewünschte Qualität erreicht. Dem kann man mit Paarprogrammierung und Schulung entgegenwirken.

Kein Ersatz für Systemtests

Auch diese stark auf Tests setzende Art der Programmierung kann nicht jeden Fehler aufdecken, insbesondere nicht Fehler, die programmextern entstehen: Timingfehler wie Thread-Deadlocks, Fehler bei der RS232-Kommunikation usw. Ebenfalls kann es an der nötigen Testabdeckung mangeln, wenn nicht alle potentiellen Eingaben einer Funktion getestet werden können. Dies ist etwa der Fall, wenn etwa die Eingabe aus sehr vielen Einzeldaten besteht; dann kann aufwandshalber nicht mehr jede mögliche Kombination von Eingabedaten getestet werden. Fehler bei Benutzungsoberfächen sind schlecht testbar, weil natürlich kein automatisierter, prüfender „Testblick“ auf die Folge der Bildschirmdarstellungen und die Verständlichkeit von Darstellung und Textelementen möglich ist. Um anderswie noch Fehler zu finden, sind Integrationstests und Systemtests erforderlich.

Literatur

Weblinks


Wikimedia Foundation.

Игры ⚽ Поможем написать реферат

Schlagen Sie auch in anderen Wörterbüchern nach:

  • Test-driven development — (TDD ) is a software development technique consisting of short iterations where new test cases covering the desired improvement or new functionality are written first, then the production code necessary to pass the tests is implemented, and… …   Wikipedia

  • Test Driven Development — Le Test Driven Development (TDD) ou en Français développement piloté par les tests est une méthode de développement de logiciel qui préconise d écrire les tests unitaires avant d écrire le code source d un logiciel. Sommaire 1 Le cycle de TDD 2… …   Wikipédia en Français

  • Test-Driven Development — Разработка через тестирование (англ. test driven development)  техника программирования, при которой модульные тесты для программы или её фрагмента пишутся до самой программы (англ. test first development) и, по существу, управляют её разработкой …   Википедия

  • Test-Driven Development by Example — Test Driven Development: By Example is a book about a software development technique by Kent Beck.Beck s concept of test driven development centers on two basic rules:#Never write a single line of code unless you have a failing automated test.… …   Wikipedia

  • Test first development — Als testgetriebene Entwicklung (auch testgesteuerte Programmierung, engl. test first development oder test driven development (TDD), manchmal auch scherzhaft Extreme Testing) ist eine Methode, die häufig bei der agilen Entwicklung von… …   Deutsch Wikipedia

  • Behavior Driven Development — (or BDD) is an Agile software development technique that encourages collaboration between developers, QA and non technical or business participants in a software project. It was originally conceived in 2003 by Dan North D.North,… …   Wikipedia

  • Behavior driven development — (ou BDD) est une méthode Agile qui encourage la collaboration entre les développeurs, les responsables qualités, les intervenants non techniques et les entreprises participants à un projet de logiciel. Il a été conçu en 2003 par Dan North comme… …   Wikipédia en Français

  • Behavior Driven Development — (ou BDD) est une méthode Agile qui encourage la collaboration entre les développeurs, les responsables qualités, les intervenants non techniques et les entreprises participants à un projet de logiciel. Il a été conçu en 2003 par Dan North comme… …   Wikipédia en Français

  • Tester Driven Development — is an Anti pattern in software development. It should not be confused with Test Driven Development. It refers to any software development project where the Software testing phase is too long. The testing phase is so long that the requirements may …   Wikipedia

  • Design-driven development — (D3) is an agile based process for creating innovative requirements to build better solutions. It works closely with SCRUM and Extreme Programming (XP) for managing and implementing those requirements. Also it can work with non agile processes… …   Wikipedia

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”