Über das Testen von PHP-Projekten im Jahr 2013

Finde den Sweet Spot
Kommentare

Johann Peter Hartmann ist CTO der Mayflower GmbH, die high-end Weblösungen für Kunden wie die Deutsche Telekom AG, ProSiebenSat.1 Media AG und Vaillant GmbH entwickelt. Daneben ist Johann eine Legende der deutschen PHP-Community und ein beliebter Speaker auf verschiedensten Technologie-Konferenzen. Aus diesem Grund hat sich Tobias Schlitt mit Ihm darüber unterhalten, wie das Testen in PHP-Projekten im Jahr 2013 aussehen sollte.

Tobias Schlitt: Bist Du froh darüber, dass PHP in Qualität heute bequem mit anderen Sprachen mithalten kann? Noch vor einigen Jahren sind wir ja als sicherheitsignorante Spaghetti-Coder bekannt gewesen. Johann-Peter Hartmann: Ja, natürlich. Wir haben 2005 unser erstes Projekt Test-driven entwickelt. Zu der Zeit war das noch hoch experimentell, auf Basis von SimpleTest und ohne jegliche CI-Infrastruktur. Seit diesen Tagen hat sich aber alles geändert – inzwischen gibt es bei uns praktisch keine Projekte mehr, die nicht mit Unit- und Akzeptanz-Tests, einer CI und der ganzen Palette von Code-Qualitätstools laufen. Und mit den aktuellen IDEs zusammen gibt das einen Workflow, der einfach Spaß macht und tatsächlich nicht ausbremst. Inzwischen sind wir auf einem Level angekommen, auf dem wir bequem mit Sprachen wie Java, Python oder Ruby konkurrieren können, was die Verlässlichkeit unseres Codes angeht. Wenn auch auf unsere Art und Weise, und nicht als einfacher Copy-Cat. Tobias: Warum nicht als Copy-Cat? Sind die ganzen Unit-Test-Frameworks nicht sehr ähnlich? Johann: Ja, natürlich; die haben meist sogar die gleichen APIs. Aber die Sprachen sind unterschiedlich. Und das betrifft nicht nur die Syntax, sondern vor allem die Nutzung und die Kultur, aus der die Entwickler stammen. Wir haben vor einigen Jahren mal eine Umfrage gemacht, warum die Architekturentscheidung zugunsten von PHP und nicht zugunsten von .NET, Java, Ruby oder Python gefällt wurde. Und – für uns PHP-Entwickler nicht überraschend – standen vor allem Kosten und schnelle Resultate sowie die Fähigkeit zur schnellen Änderung im Vordergrund. Wer sich für PHP entscheidet, der möchte nicht lange im Vorfeld planen und dann sechs Monate auf den ersten Release warten – er möchte mit wenig Planung auskommen, schnelle Resultate sehen und diese dann gegebenenfalls anpassen. Und wie es der Zufall so will, sind das genau die Anforderungen, die sich im Internet noch verstärkt ergeben, denn dort ist viel Software innovativ, und man weiß noch gar nicht, ob jemand die Applikation wirklich nutzen möchte. Dazu kommt Open Source und die Vielzahl an bestehenden Lösungen für typische Probleme wie Content Management oder E-Commerce – und schon hat man die perfekte Universalsprache für die Probleme des Internets. Damit ändert sich aber das Testen. Während eine klassische Offline-Applikation mehrere Jahre mit einem stabilen Unit-Test verbringen kann, ändern sich online auch gerne mal die Kern-Workflows halbjährlich, und nicht nur die Business-Logik, sondern auch die Unit-Tests müssen angepasst werden. Das heißt, dass sich der Test schneller rentieren muss – und damit ändert sich die ganze Anforderung an die Qualität der Software. Tobias: Was heißt das konkret? Andere Tests, weniger Tests oder vielleicht sogar gar keine Unit-Tests? Johann: Gar keine Unit-Tests, schließlich war PHP-Nuke auch über Jahre die erfolgreichste Online-Software, ohne dass es einen Test gab. Nein, das würden uns unsere Nutzer wohl nicht mehr verzeihen. Das heißt aber, dass für uns Test-Effizienz mehr im Vordergrund steht. Wenn ich eine Software lange in ähnlicher Form verwende möchte ich einen Test so schreiben, dass er eine stabile API bedient und die Stabilität dieser Komponente über die Refactorings hinweg sicherstellt. Die oberen Layer werden durch Akzeptanztests und Regressionstests gesichert, die ebenfalls im Wesentlichen erhalten bleiben. Wenn ich allerdings davon ausgehe, dass sich alles ändern kann und wird – inklusive der grundlegenden Business-Hypothesen – dann sieht die Situation anders aus. Dann möchte ich zwar auch noch Verlässlichkeit, aber nicht auf Kosten der Produktivität. Ich weiß, dass ich bei jeder zweiten Änderung auch den Test anfassen muss, weil sich die geänderte Business-Anforderung partout nicht an meine Abstraktionsschnitte halten mag. Und ich möchte nicht, dass eine Änderung von zwei Zeilen im eigentlichen Code eine Änderung von 20 Zeilen im Testcode nach sich zieht. In diesem Fall würde ich nämlich aller Wahrscheinlichkeit nach in meinem Test-Code zehn mal mehr Fehler als in meinem eigentlichen Code machen, und im Resultat wären meine Tests selbst nur so mittel vertrauenswürdig. Also suche ich mir die Kombination von Tests, die meinen Änderungen am besten entgegen kommt. Da, wo ich viele Änderungen habe, muss die Absicherung durch Tests einfach geschehen – und das kann unter Umständen am besten auf einer hohen Ebene geschehen, die den ganzen Kernprozess absichert. Also zum Beispiel über Behat oder Jasmine. Und mit den Ebenen darunter halte ich es genau so: ich setze mit meinen Tests da an, wo ich am wenigsten Kosten für Änderung, aber im Gegenzug am meisten Stabilität bekomme. Tobias: Heißt das, dass ich nicht Test-driven arbeiten sollte? Johann: Nein, Test-driven ist hervorragend und ist nur zu empfehlen. Das ist die beste Versicherung gegen schlecht durchdachten Code, gegen wirre Abhängigkeiten und gegen seltsame APIs, die man für Geld bekommen kann. Aber das sichert jeweils nur den Teil der Software, den ich gerade neu entwickle. Dadurch, dass jedes Teil für sich korrekt ist, muss ja nicht die Kombination aller Teile ebenfalls korrekt sein. Aus den Metallteilen vom Eiffelturm hätte man auch ein ganz anderes Gebäude bauen können, das sofort in sich zusammenstürzen muss – also in der Summe massiv fehlerhaft ist. Ich brauche also auf jeden Fall Tests über die Unit hinaus, um auch die Kombination und Kooperation der Komponenten zu sichern. Aber ich kann ja auch von außen nach innen Test-getrieben arbeiten, also Behavior-driven entwickeln. Das macht mir keine sauberen APIs, aber es sichert mir das Zusammenspiel. Aber auch diese Tests müssen dann wieder effizient gegenüber Änderungen sein. Und damit haben viele Test-Frameworks, insbesondere Selenium, massive Probleme. Es gibt also keinen goldenen, perfekten Weg – dieser würde fast zwangsläufig in entweder zu wenigen oder unsinnigen Tests münden – sondern es geht um den Sweet Spot für das eigene Projekt. Die Kombination von Tests, die nur wenig Test-Waste erzeugt und trotzdem Fehler in den Core-Workflows zuverlässig erkennt. Tobias: Und wie hat Euch Qafoo dabei geholfen? Johann: Toby hat bei uns einen Workshop gemacht und er war so nett, den an unserem Problem entlang zu gestalten. „Wie teste ich sinnvoll? Wie teste ich effizient?“. Wir testen seit 2005, uns braucht also niemand die Syntax oder die Funktion von Mock-Objekten zu erklären. Aber wir wollten wissen, wie wir sinnvoll testen. Wo der Sweet Spot ist, bei dem man nicht zu viele Tests hat; und auch nicht zu wenige. Und wie ich vorgehen muss, damit ich dahin komme. Und genau an der Stelle hat der Workshop angesetzt und geholfen. Es wurden Erfahrungen vermittelt – und noch wichtiger – im Rahmen des Workshops selbst neue Erfahrungen für die Kollegen erzeugt. So bekommen wir ein Gefühl dafür, wann welcher Ansatz Sinn ergibt. Wie wir die Architektur und das Design gestalten müssen, um die Kosten von Tests deutlich zu senken. Wie wir aus der Falle des Inner-Platform-Antipattern kommen, bei dem wir Infrastruktur und Business-Logiken einen hässlichen Mock-Zwilling beiseite stellen. Eben: wie man effizient Tests schreibt, die einem nicht nach zehn Monaten so auf die Nerven gehen, dass man sie eigentlich nur noch deaktivieren statt anpassen will. Und das hat Tobias hervorragend hinbekommen, auf die ihm typische unterhaltsame Art. Tobias: Was kann man daneben noch machen, um ein gut getuntes, effizientes Test-Setup zu bekommen? Johann: Coding Dojos! Bitte sofort googlen und einmal mit dem eigenen Team ausprobieren. Das ist, nach dem Workshop, der perfekte Weg, um eigenes Erfahrungswissen für gute Tests aufzubauen. Oder um Test-driven einzuführen, oder um ein Gefühl für Pair-Programming zu bekommen. Oh, und bitte glaubt nicht an eine Wunderwaffe, die alle Eure Qualitätsprobleme magisch löst. Tobias: Johann, danke dass Du Deine Erfahrungen mit uns geteilt hast.

Das Interview führte Tobias Schlitt von Qafoo. Auf dem Qafoo-Blog behandeln er und sein Team regelmäßig Themen Qualitätssicherung, JavaScript und vieles mehr. Außerdem ist er Autor der Kolumne Quality Time im PHP Magazin.

Aufmacherbild: Job Seeker, Job Career Concept Present By Group of Businessman With Red Interview Sign on Hand Isolated von Shutterstock / Urheberrecht: DeiMosz

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -