Open Source im professionellen Einsatz
Linux-Magazin 08/2013
© linkje, Photocase.com

© linkje, Photocase.com

Loginsystem, agil entwickelt

Am Anfang war der Test

Test-driven Development mit einer nebenbei generierten Testsuite verspricht Code mit weniger Fehlern. Michael "Perlmeister" Schilli betritt gleich den Pfad der Agilität und findet am Wegesrand zufällig ein passendes, nagelneues CPAN-Modul.

642

Vor einigen Wochen hatte mich mein Arbeitgeber auf einen Kurs zum Thema Test-driven Development (TDD) geschickt. Testgetriebenes Entwickeln zählt zu den so genannten agilen Methoden. Um mein gerade erworbenes Wissen in die Praxis umzusetzen, stelle ich den heutigen Perl-Snapshot ganz in den Dienst dieses Prinzips. Schnelle und flexible Entwickler legen sofort los, ohne auf Details zu achten. Sie schreiben stets zuerst einen Test, bevor sie sich an die Implementierung einer Funktion machen. Darum wächst die Testsuite automatisch mit relevanten Tests zu Funktionen des Systems mit. Unsauberen Code säubern sie später mittels Refactoring, was dank des durch die Testsuite bereitgestellten Sicherheitsnetzes gefahrlos gelingt.

Online PLUS

In einem Screencast demonstriert Michael Schilli das Beispiel: http://www.linux-magazin.de/plus/2013/08

Nichts als Fehler – und das ist richtig so

Die vor dem Schreiben einer Funktion entwickelten Tests schlagen naturgemäß fehl, da das gewünschte Feature zunächst entweder noch gar nicht existiert oder nur teilweise oder fehlerhaft implementiert ist. Steht später der Code, schaltet die Testsuite auf Grün, was eine Entwicklungsumgebung wie Eclipse sogar optisch so anzeigt.

Um zum Beispiel eine Klasse »User.pm« für ein Loginsystem zu schreiben, das später Methoden wie »login()« unterstützen soll, legt der TDD-Apostel zunächst einen Testfall an. Der prüft, ob sich die gewünschte Klasse überhaupt instanzieren lässt. Listing 1 zeigt die Testdatei für einfache Testfälle »Basic.pm« . Sie liegt im Verzeichnis »t« , welches das brandneue CPAN-Modul Test::Class::Moose nutzt. Letzteres führt alle Methoden, die mit dem Präfix »test_« beginnen, mit den darin enthaltenen Testroutinen aus.

Listing 1 definiert »test_constructor()« und setzt darin den Befehl

can_ok 'User', 'new';

aus dem Modul Test::More ab. Damit prüft »test_constructor()« , ob die Klasse »User« dazu fähig ist, ihren Konstruktor »new« aufzurufen.

Listing 2 zeigt ein Skript, das die Testsuite ablaufen lässt. Zunächst lädt es mittels »Load« alle Perl-Module mit der Endung ».pm« , die es in den angegebenen Unterverzeichnissen ».« und »t« findet. Die Methode »runtests()« durchstöbert daraufhin alle »test_*« -Routinen. In dieser Projektphase existiert die Klasse »User« allerdings noch nicht, und so schlägt die Testsuite in »test_constructor()« fehl ( Abbildung 1 ).

Listing 1

Basic.pm

1 package TestsFor::User;
2 use Test::Class::Moose;
3
4 sub test_constructor {
5   can_ok 'User', 'new';
6 }
7
8 1;

Listing 2

runtests

1 #!/usr/local/bin/perl -w
2 use Test::Class::Moose::Load qw(t .);
3 Test::Class::Moose->new->runtests;

Abbildung 1: Zunächst schlägt die Testsuite Alarm, denn die Klasse User hat noch niemand geschrieben.

Erfolgserlebnisse

Der Test-driven-Entwickler hat dies zweifellos erwartet und setzt nun alles daran, Code hinzuzufügen, bis die Testsuite erfolgreich durchläuft. Da die Klasse nicht existiert, legt er eine neue Datei »User.pm« an und schreibt hinein:

package User;
use Moose;
1;

In Würde ergraute Perlpanther reiben sich hier vielleicht ungläubig die Augen, denn das Package »User« definiert keinen Konstruktor »new()« , der einen Objekthash »$self« mittels »bless()« mit einem Paket verschweißt. Das CPAN-Modul Moose [2] erledigt all dies hinter den Kulissen, sodass jedes Paket, das Moose hereinzieht, automatisch einen Konstruktor »new()« besitzt. Ein erneuter Aufruf der Testsuite mit »./runtests« liefert:

<!-- START: including template: design/standard/templates/content/datatype/view/ezxmltags/emphasize.tpl (design:content/datatype/view/ezxmltags/emphasize.tpl) -->
[...]
<!-- STOP: including template: design/standard/templates/content/datatype/view/ezxmltags/emphasize.tpl (design:content/datatype/view/ezxmltags/emphasize.tpl) -->

ok 1 - TestsFor::User

Die Suite findet also die neue ».pm« -Datei, die in ihr enthaltene Klasse, und führt den Konstruktor »new()« erfolgreich aus.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 3 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Perl-Snapshot

    Passend zum Titelthema: Mike
    Schilli nutzt Mouse und Moose, um
    Distributionsrepositories abzufragen.

  • Kontrolle ist besser

    Eine Testsuite hilft Fehler zu korrigieren und Teile des Systems umzuschreiben, ohne die bestehende Codebasis dabei zu ruinieren. Die unbestechlichen Kontrolleure heißen etwa Test::More oder Test::Deep.

  • Browser ferngesteuert

    Das Testen komplexer Webapplikationen erfordert nicht unbedingt teure proprietäre Tools wie Test Director oder Silk Performer: Selenium gibt's umsonst. Es steuert alle gängigen Browser unter verschiedenen Betriebssystemen fern und lässt sich unter anderem mit Perl programmieren.

  • Alles unter Kontrolle

    Bei jeder Änderung an einem Programm besteht die Gefahr, dass unbemerkt neue Fehler entstehen. Mit Unit-Tests kontrollieren Entwickler, ob alle Bausteine ihres Programms erwartungsgemäß funktionieren. Die Skriptsprache Ruby bringt von Haus aus ein leistungsfähiges Modul fürs Unit Testing mit.

  • Perl-Snapshot

    Ein neuer Service auf Travis-ci.org listet fein säuberlich Github-Projekte eines Entwicklers auf, schickt den Code bei jedem Push durch deren Testsuites und gibt Rückmeldung, falls der Build bricht. In den zurückgelieferten Testergebnissen machen neugierige Perl-Skripte Zusatzinformationen sichtbar.

comments powered by Disqus