Software

Artikelserie Test: Unit, Functional, Coverage

Als Entwickler sollte man sich immer darauf verlassen können, dass der Code, den man schreibt, so funktioniert wie er soll, und dass er keine Nebenwirkungen auf ältere, bereits bestehende Funktionen hat. Zu diesem Zweck gibt es automatische Tests. Wie mein Team bei der punkt.de diese verwendet, kann man in der Artikelserie über Tests nachlesen.  

Im ersten Teil der Serie ging es darum, dass geprüft wird, dass unser Code immer den selben Stil hat, sauber verwendet wird und Fremdlibraries aktuell sind. Nun wollen wir prüfen, dass der Code auch wirklich die Funktion erfüllt, die er soll.

Unit-Tests – klein aber fein

Der erste Schritt dazu sind Unit-Tests, welche wir insbesondere im Backend für den PHP-Code schreiben. Die Tests selbst werden mit dem Tool phpUnit umgesetzt.

Die Idee davon ist, dass Code schreibt, welcher von einer Klasse, welche man Testen möchte, einzelne Methoden aufruft und prüft, dass bei entsprechend befüllten Argumenten immer das korrekte Ergebnis ausgegeben wird.

Ein kleiner Beispieltest für einen einfachen Validator:

Für Unittests gibt es ein paar kleine Ideen: 

  1. Man testet das „public Interface“ einer Klasse: Normalerweise will man nur die Methoden testen, die wirklich von außen aufgerufen werden, da diese im Endeffekt die Funktionalität widerspiegeln
  2. Dependencies – insbesondere Fremdcode – wird gemockt: Da man genau die eine Funktion testen möchte, und nicht einen großen Funktionen-Baum (mit Code, den man gar nicht unter Kontrolle hat), sagt man phpUnit „rufe nicht die Original-Dependency auf, sondern gib an der Stelle immer X zurück“
  3. AAA – Arrange, Act, Assert: Ein Test ist dann am einfachsten zu verstehen, wenn man zuerst alles vorbereitet (Arrange), dann alles ausführt (Act) und am Ende prüft, ob die Ergebnisse korrekt waren (Assert)
  4. Keine Logik in Tests: Die Logik, die man testet, ist innerhalb der getesteten Methoden. Wenn man zu viel Logik innerhalb eines Tests schreibt, dann braucht man einen Test für den Test, und damit hat man zu wenig Gewinn

Natürlich gibt es Ausnahmen zu diesen Ideen; Beispielsweise hatten wir im Team vor Jahren einen Test, der in einer Klasse genau eine protected Methode getestet hat, da diese das Kernstück der Klasse war und alle public Methoden nur diese protected aufgerufen hatten. Damit konnten wir uns Testaufwand sparen. Auch kann man zu viel Mocken und beispielsweise dafür sorgen, dass man nicht mehr echten Code testet, sondern nur noch die Mocks. Dies sind Fallstricke, die man immer wieder prüfen muss und die bei jedem Test wieder auf’s neue Relevant werden.

Mit Unit-Tests wissen wir nun, dass unsere Puzzelteile im Code korrekt funktionieren, nun müssen wir prüfen, dass diese auch korrekt zusammengesetzt werden.

Funktionale Tests – die Summe der kleinen Teile

In den Unit-Tests wird nur eine einzelne Codestelle aufgerufen. Wir wollen nun wissen, dass die Codestellen zusammen mit dem verwendten Backend-Framework (in unserem Fall TYPO3 Extbase) in der Anwendungslogik korrekt funktionieren. Zu diesem Zweck schreiben wir Funtional Tests nach der entsprechenden TYPO3-Doku

Dadurch, dass wir die Tests innerhalb eines TYPO3-Contextes aufrufen, stellen wir sicher, dass das „Außenherum“ korrekt initialisiert ist. Anschließend können wir Tests schreiben, welche beispielsweise Zugriff auf eine (teilweise generierte) Datenbank haben – in unserem Fall testen wir beispielsweise einen Importer. 

Wir bereiten eine CSV-Datei vor, rufen innerhalb des Tests die Import-Methode auf und können danach in der Datenbank verifizieren, dass die Zeilen genau den Stand haben, den wir erwarten – wieder sehen wir AAA (Arrange, Act, Assert). Importer sind hier nur ein Beispiel, man kann theoretisch auch Scheduler-Tasks, Controller-Actions, Middlewares und anderes aufrufen. 

Wir wissen, was wir testen – aber was testen wir genau?

Ein Thema, welches bei uns im Team derzeit noch nicht dediziert umgesetzt wird, aber zukünftig eingeplant wird, ist das Erfassen der Code Coverage. Man kann in phpUnit konfigurieren, welche Quellcode-Dateien theoretisch Teil des Testumfeldes sind, und phpUnit erfasst dann für diese Dateien, welche Methoden, Codezeilen und ähnliches innerhalb der Tests wirklich aufgerufen werden. 

Daraus kann man sich dann eine Liste erstellen, in der man sieht, ob man z.B. in einer komplexen Methode Pfade entwickelt hat, welche nicht getestet sind, oder ob es ungetestete Klassen gibt. Außerdem wird eine Statistik erstellt, welche prozentual angibt, wie hoch der Anteil des getesteten Codes wirklich ist. 

Ausblick

Im ersten Artikel hatten wir auf die Qualität des Codes geschaut, in diesem Teil auf die Funktionen innerhalb der php-Klassen. Im nächsten Teil unserer Serie werden wir darauf schauen, wie wir Teile unserer eigentlichen Anwendung testen.

Agiles Testing und Prozess-Know-how für Ihr Team:

Egal ob Agentur, Industrieunternehmen oder ein eigenständiges Entwicklerteam: Wenn Sie agile Testing-Prozesse etablieren oder weiterentwickeln wollen, unterstützen wir Sie mit unserem Know-how – sei es durch praxisorientierte Workshops oder durch direkte, projektbezogene Mitarbeit. Wir begleiten Sie von der Einführung agiler Testmethoden über die Optimierung bestehender Abläufe bis hin zur Entwicklung und Umsetzung individueller Testing-Strategien. Sprechen Sie uns gerne an, um gemeinsam Ihre Qualitätssicherung und Entwicklungsprozesse auf ein neues Level zu heben!

Firmenkontakt und Herausgeber der Meldung:

punkt.de GmbH
Sophienstr. 187
76185 Karlsruhe
Telefon: +49 (721) 9109-0
Telefax: +49 (721) 9109-100
https://www.punkt.de

Ansprechpartner:
Fabian Stein
Geschäftsführer
Telefon: +49 (721) 9109-124
E-Mail: stein@punkt.de
Für die oben stehende Story ist allein der jeweils angegebene Herausgeber (siehe Firmenkontakt oben) verantwortlich. Dieser ist in der Regel auch Urheber des Pressetextes, sowie der angehängten Bild-, Ton-, Video-, Medien- und Informationsmaterialien. Die United News Network GmbH übernimmt keine Haftung für die Korrektheit oder Vollständigkeit der dargestellten Meldung. Auch bei Übertragungsfehlern oder anderen Störungen haftet sie nur im Fall von Vorsatz oder grober Fahrlässigkeit. Die Nutzung von hier archivierten Informationen zur Eigeninformation und redaktionellen Weiterverarbeitung ist in der Regel kostenfrei. Bitte klären Sie vor einer Weiterverwendung urheberrechtliche Fragen mit dem angegebenen Herausgeber. Eine systematische Speicherung dieser Daten sowie die Verwendung auch von Teilen dieses Datenbankwerks sind nur mit schriftlicher Genehmigung durch die United News Network GmbH gestattet.

counterpixel