Facebook
Twitter
Google+
Kommentare
9

Test first = besserer Code?

Eigentlich wollte ich ja heute ein wenig über ein weiteres Caching Buzzword philosophieren. Stale-on-revalidate wäre es gewesen. Da wir aber in den gestrigen Kommentaren schon genug darüber gesprochen haben, habe ich mich entschieden den Tag doch einem anderem Thema zu widmen. Ok, vielleicht werde ich da Thema jetzt nicht gänzlich ausschöpfen, aber ein paar Gedanken zum test first Ansatz möchte ich heute doch noch los werden.

Was sich hinter test first versteckt ist einfach. Bevor ich meine Schnittstelle mit Leben, also dem Code fülle, schreibe ich meine Tests. Das geht natürlich nur deshalb, weil man vor der ersten Zeile der konkreten Implementierung schon alle nötigen Schnittstellen fertig hat. Und genau da haben wir schon den Knackpunkt. Wir müssen uns vorher über die saubere Beschaffenheit unserer Interfaces kümmern. Wir fangen nicht einfach an drauf los zu programmieren. Und meiner Erfahrung nach ist das auch gut so, denn oft fällt einem später ein, dass man das gar nicht so machen kann. Hätte man doch schon am Anfang bis zum Ende gedacht. Ok, das ist also der erste große Bonuspunkt des „frühzeitigen“ Testen: wohldefinierte Schnittstellen.

Das reicht natürlich nicht. Wenn ich im vornherein schon Gedanken darüber mache, dass ich den Code, den ich da verbreche auch noch testen muss, werde ich die Methoden schön klein halten. Schön klein bedeutet ja schließlich eine geringe Komplexität und damit eine einfache Testbarkeit. Den „big-ball-of-mud“ wird man so wohl kaum produzieren können, denn wer schreibt schon gerne hunderte von Tests im voraus, wenn es auch anders geht. Zweiter Vorteil ist also, dass man gleich so programmiert, dass der Code testbar ist. Und testbarer Code ist was wunderbares.

So das waren jetzt klare Vorteile für das Schreiben der Test vor Vorfeld. Gibt bestimmt noch viele mehr, aber die hebe ich mir für den ein oder anderen neuen Beitrag auf.

Über den Autor

Nils Langner

Nils Langner ist der Gründer von "the web hates me" und auch der Hauptautor. Im wahren Leben leitet er das Qualitätsmanagementteam im Gruner+Jahr-Digitalbereich und ist somit für Seiten wie stern.de, eltern.de und gala.de aus Qualitätssicht verantwortlich. Nils schreibt seit den Anfängen von phphatesme, welches er ebenfalls gegründet hat, nicht nur für diverse Blogs, sondern auch für Fachmagazine, wie das PHP Magazin, die t3n, die c't oder die iX. Nebenbei ist er noch ein gern gesehener Sprecher auf Konferenzen. Herr Langner schreibt die Texte über sich gerne in der dritten Form.
Kommentare

9 Comments

  1. Mensch Nils, wieso hast du das Buzzword Test-Driven-Developement nicht im Artikel erwähnt? Ich bin enttäuscht! 😉

    Sehr guter Artikel, den wichtigsten Punkt für diesen Ansatz sehe ich im übrigen bei den wohldefinierten Schnittstellen. Das macht den Code in letzter Konsequenz auch wartbarer und lesbarer und das ist ja das, was wir vor allem wollen.

    Reply
  2. Es gibt noch einen Punkt: der Test wird so ein Teil der Anforderungsdokumentation. Das sorgt in großen Teams dafür, dass Anforderungsgeber und -empfänger einander richtig verstehen.
    In diesem Fall kommen die Anforderungen natürlich von einem Entwickler und gehen an einen anderen Entwickler – der Kunde ist dabei nicht direkt involviert.

    Der nächste Vorteil ist: wenn die Schnittstelle bereits bekannt ist, kann ein anderer Teil des Teams schon einmal weiterentwickeln, ohne auf die Implementierung der Funktion warten oder anschließend neu geschriebene Funktionen durch ein Refactoring jagen zu müssen. Ein Skeleton mit Dummy-Rückgabewerten im Trunk genügt. Das macht es eventuell hinterher sogar einfacher, wenn der Entwickler seinen Dev-Branch zurück in den Trunk merged.

    Einfach zu realisieren: PHPUnit erlaubt simple Testfälle über die Annotation „@assert“ direkt im Kommentarblock der Funktion zu definieren. Der Entwickler generiert sich daraus seinen TestCase.

    Test-first funktioniert immer genau dann nicht, wenn entwickelt wird, ohne sich vorher Gedanken über vollständige Anforderungen oder ein gutes Design zu machen. Letzteres findet man leider dank Termindruck noch viel zu häufig. Bei viel zu vielen Projekten entstehen Architektur und Design noch „on-the-fly“ während der Implementierung.

    Reply
  3. Vielleicht solltest du noch dabei schreiben, dass ein solches Vorgehen vor allem für erfahrene Programmierer Sinn macht, denn wenn man täglich seine Schnittstellen ändern muss, weil man nicht die Erfahrung hat, bringt das ganze eher Mehrarbeit als Ersparnisse.

    Ich kann Tom auch nur zustimmen, all zu häufig hat man nicht die Tage Zeit, sich über die Architektur im Detail Gedanken zu machen. Immer ist es also nicht anwendbar, in einer idealen Welt aber erstrebenswert.

    Reply
  4. Ich würde das Thema auch unter dem Begriff Test-Driven-Development (TDD) zusammenfassen.
    Es führt meist zu einer guten Architektur, da der wichtigste Punkt automatisch erfüllt ist: wohldefinierte, getestete Schnittstellen.
    Und wenn man Schwächen erkennt ist man auf jeden Fall in der Lage Refactoring zu betreiben, was im herkömmlichen Umfeld nicht immer gegeben ist.

    Weiterer interessanter Punkt: Ist TestFirst oder TDD automatisch agil oder ist das eine Nebenbedingung?

    Reply
  5. Jo, TDD wäre passender. Zum Punkt, es sei eher für Fortgeschrittene geeignet, muss ich allerdings widersprechen! Es ist für jeden geeignet. Den es erleichtert die Arbeit, egal welches Level der Entwickler hat.

    Reply
  6. Dem würde ich entschieden widersprechen. Ein unerfahrener Entwickler kann nicht selbst von sich aus test-driven entwickeln. Wenn einmal die Architektur steht, ist das sicherlich dann möglich, aber zuvor sehe ich das nicht. Auch weil er wahrscheinlich erst einmal einen Crash-Kurs im Unit-Testing benötigt. Dann lieber gar kein TDD anstatt schlechtes TDD, denn damit ist keinem geholfen.

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen