• Test first = besserer Code?

    von am 10. Dezember 2009
    Dieser Artikel wurde auf Wunsch der phphatesme Leser verfasst und wurde über die Ideenschmiede eingereicht. Falls du auch eine Idee für einen Artikel hast, dann füge sie doch einfach hinzu.

    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.

    Nils Langner

    Auch wenn Ihr es mir nicht glauben werdet, aber ich habe nichts gegen PHP. Ich rege mich einfach nur gerne auf. Ok so schlimm ist es auch nicht. Eigentlich wollte ich schon immer einen Blog haben und da ...

    Zum Profil von Nils Langner

    9 Kommentare »


    • Ulf
      am 10. Dezember 2009 um 09:35 Uhr

      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.


    • Cem Derin
      am 10. Dezember 2009 um 10:05 Uhr

      Lustig, da habe ich doch heute auch darüber geschrieben (siehe angegebene URL), dass ich Methoden möglichst kurz halte, damit sie einfacher zu warten sind ;)


    • Tom
      am 10. Dezember 2009 um 10:19 Uhr

      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.


    • PHPGangsta
      am 10. Dezember 2009 um 11:43 Uhr

      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.


    • Cem Derin
      am 10. Dezember 2009 um 12:49 Uhr

      Warum gibst du meinen Kommentar denn nicht frei, Nils? :(


    • Nils Langner
      am 10. Dezember 2009 um 13:03 Uhr

      @Cem: Weil er als Spam erkannt wurde ;) War keine Absicht!


    • Martin
      am 10. Dezember 2009 um 13:24 Uhr

      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?


    • Sebastian
      am 10. Dezember 2009 um 16:27 Uhr

      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.


    • Ulf
      am 10. Dezember 2009 um 16:50 Uhr

      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.

    RSS Feed für Kommentare zu diesem Artikel. TrackBack URL

    Hinterlasse einen Kommentar

    Werbung
    PHP Magazin
    Ausgabe 02/2010

    Dieses Mal mit Artikeln zu den Themen OpenSocial und Apache Shindig, Graphentheorie, Smarty3

    t3n
    Ausgabe 19

    Social Media (R)evolution. Weitere Themen sind noSQL, Crowdsourcing ...

    PHP Journal
    Ausgabe 2/2010

    PHP & Windows optimal nutzen, die besten PHP-CMS im Überblick, Google-API mit Zend Framework nutzen.

    Wir wurden schon öfters gefragt, ob man uns nicht irgendwie unterstützen kann. Die Antwort war immer einfach: Klar! Am einfachsten ist es eure nächsten Einkäufe bei Amazon über unsere Link abzuwickeln. Damit würdet ihr uns schon sehr helfen. Über Co-Autoren freuen wir uns aber noch mehr.