Bild-CAPTCHA
Geben Sie die Zeichen ein, die im Bild gezeigt werden.
Schreiben Sie uns hier!

Sie sind hier

Automatisierte Tests mit Codeception

Automatisierte Tests mit Codeception ermöglichen ein Testen des Frontends einer Website. Da JavaScript genutzt werden kann und Aktionen wie Maus-Bewegungen und Klicks simuliert werden können, sind Tests möglich, die sehr nah am Verhalten eines "echten" Benutzers sind.

Was ist Codeception?

Codeception ist ein Testing-Framework das auf PHPUnit basiert und Komponenten von Symfony2 und Mink verwendet.

Tests mit Codeception sind nicht auf ein bestimmtes CMS (Content Management System) oder eine Plattform wie .NET ausgelegt, sondern können fast überall eingesetzt werden. Es sind nicht nur Acceptance-Tests möglich, welche üblicherweise verwendet werden, um das Frontend einer Website zu testen. Mit Codeception können auch Functional-Tests, zum Testen von Funktionen in einer Web-Anwendung (die beispielsweise auf Symfony, Zend oder Yii basieren), durchgeführt werden. Die dritte Art von Tests, die mit Codeception umgesetzt werden können, sind Unit-Tests mit denen einzelne Komponenten innerhalb einer Anwendung getestet werden können.

Dieser Artikel wird sich auf Acceptance-Tests in Codeception mit dem Selenium Webdriver beschränken.

In Acceptance-Tests mit Codeception wird ein Webdriver verwendet, der entweder die einzelnen Schritte der Tests in einem echten Browser ausführt oder diese Schritte simuliert. Die verschiedenen Webdriver haben, entsprechend ihrer Möglichkeiten, eine unterschiedliche Auswahl an Aktionen, die sie beim Testen ausführen können.

Es können je nach Anforderung verschiedene Webdriver verwendet werden. Der Selenium Webdriver bietet die Möglichkeit, Tests in einem echten Browser auszuführen (und den Testabläufen dabei zuzuschauen), JavaScript in den Tests zu verwenden und die wirkliche Sichtbarkeit eines Elements zu überprüfen (anstatt nur zu prüfen, ob das Element im Quelltext zu finden ist). Der Nachteil am Testen über den Selenium Webdriver ist, dass die Durchführung der einzelnen Tests eine Menge Zeit in Anspruch nimmt.

Eine Alternative wäre, den PHP-Browser zu verwenden. Tests mit diesem Browser werden nicht in einem echten Browser ausgeführt, was verschiedene Vor- und Nachteile hat. In Tests, die über den PHP-Browser laufen kann nur geprüft werden, ob ein Element vorhanden ist, nicht aber ob es wirklich sichtbar ist. Ein weiterer Nachteil ist, dass der PHP-Browser kein JavaScript verwenden kann und die Auswahl an Funktionen etwas eingeschränkt ist. Dafür werden die Tests sehr schnell ausgeführt und es wird lediglich PHP 5.3 und CURL benötigt.

Mit den Acceptance-Tests in Codeception kann das Verhalten eines "echten" Users genau imitiert werden. Dazu sind Aktionen wie Warten, Scrollen, Tastenkombinationen drücken oder Maus-Bewegungen über bestimmte Elemente möglich. Die Tests prüfen nicht einfach nur, ob das Gesuchte irgendwo im HTML-Code der Seite zu finden ist, sondern kontrollieren, ob z. B. das gesuchte Element wirklich sichtbar ist (hierfür wird der Selenium Webdriver benötigt). So schlägt ein Test beispielsweise fehl, wenn er auf einen Button klicken soll, der von einem anderen Element verdeckt wird.

Wenn Codeception eingerichtet wurde, ist das Schreiben der Tests einfach. Auch Jemand ohne Programmiererfahrung könnte nach kurzer Einführung eigene Tests schreiben. Die Syntax ist sehr einfach gehalten und ist, auch ohne den Kontext zu kennen, problemlos verständlich.

Wofür braucht man automatisierte Tests?

Oft werden Frontend-Tests benötigt, um sicherzustellen, dass nach Website-Änderungen alles noch funktioniert, wie vorgesehen und alles dort positioniert ist, wo es angezeigt werden soll. Auch während oder kurz nach der Entwicklung einer neuen Website werden Tests benötigt.

Das Testen des Frontend's einer Website von Hand zu erledigen, erfordert eine Menge Konzentration & Zeit und kann dabei schnell ermüdend sein. Auf einem umfangreichen System besteht die Gefahr, dass Fehler übersehen oder aufgrund von mangelnder Übersichtlichkeit einzelne Komponenten vergessen werden. Dies kann mit automatisierten Tests nicht mehr passieren.

Codeception-Tests bieten sich an, um Zeit zu sparen und mögliche Fehlerquellen auszuschließen.

Was kann mit Codeception getestet werden?

Da Codeception, wenn es über den Selenium Webdriver läuft, JavaScript nutzen kann und verschiedene User-Aktionen nachgeahmt werden können, stehen hier viele Möglichkeiten zur Auswahl. Die Tests können unter anderem die Zugänglichkeit von Unterseiten, das Ausfüllen von Formularen, Einträge in der Datenbank, die Sichtbarkeit von bestimmten Elementen (wie z. B. Fehlermeldungen) oder Weiterleitungen prüfen.

Für die Frontend-Tests stellt der Selenium Webdriver eine Reihe von vorgefertigten Funktionen bereit. Wenn diese nicht genügen, können eigene Funktionen geschrieben und hinzufügen werden. Außerdem ist es möglich PHP-Code innerhalb der Tests zu verwenden.

Die Tests können auf allen üblichen Browsern, verschiedenen Versionen dieser Browser und in allen Fenstergrößen ausgeführt werden. Ein Beispiel für einen Anwendungsfall wäre eine Testreihe, die über eine Website surft, alle Formulare ausfüllt und abschickt, prüft ob Buttons wie Login oder Registrierung vorhanden und sichtbar sind, einen neuen Inhalt anlegt und einen Kommentar schreibt. Wenn einer der enthaltenen Tests fehlschlägt, wird ein Screenshot und der HTML-Code der Seite des kritischen Punktes gespeichert.

Aufbau von Tests

In diesem Abschnitt wird die Funktionsweise und der Aufbau von Tests in Codeception etwas näher erläutert. Mit Hilfsmitteln wie Pages und Steps kann das Arbeiten mit Codeception deutlich vereinfacht und viel Zeit gespart werden.

Grundsätzlicher Aufbau

Die Tests selbst sind Funktionen, die innerhalb einer so genannten "Cest" liegen. Eine Cest könnte beispielsweise alle Tests enthalten, die benötigt werden, um sich auf einer Website anzumelden und einen neuen Inhalt anzulegen. In einer Cest stehen Hooks bereit, die vor und nach dem eigentlichen Test ausgeführt werden können. In diesen Hooks können unter anderem Steps (Näheres zu Steps unter dem Punkt Hilfsfunktionen) untergebracht werden die z. B. einen User-Login vor dem eigentlichen Test machen oder nach dem Test die angelegten Inhalte wieder löschen.

Die verschiedenen Arten von Tests, wie Acceptance, Functional, Unit und API werden in Codeception als "Suite's" bezeichnet. Es besteht die Möglichkeit, alle Tests in einer Suite, nur eine einzelne Cest oder nur einen Teil einer Cest auszuführen.

Für viele der einzelnen Schritte in einem Test muss definiert werden, welches Element gemeint ist. Dieser sogenannte "Selector" kann entweder über CSS-Klassen oder ID's angegeben werden. Außerdem besteht die Möglichkeit, regular expressions in den Selectors zu verwenden. Ebenfalls ist es möglich, als Selector z. B. den Text eines Buttons anzugeben, auf den ein Klick ausgeführt werden soll. Da es häufig notwendig ist, diese Selectors mehrfach zu verwenden, gibt es das Hilfsmittel "Pages". In einer Page werden den Selectors Variablen zugewiesen, die dann überall in den Tests verwendet werden können. Das erspart viel unnötige Arbeit.

Hilfsfunktionen

Für Schritte, die häufig wiederverwendet werden, können "Steps" angelegt werden. In diesen Steps können Vorgänge, wie Login oder das Bestätigen einer Cookie-Zustimmung, festgelegt werden. Diese Steps können dann etwa in der "_before"-Funktion (die vor dem eigentlichen Test ausgeführt wird) oder innerhalb von Tests genutzt werden.

Es stehen einige "Hooks" zur Verfügung, welche für das Testen hilfreiche Funktionen mitbringen. Eine dieser Hooks ist bereits erwähnt worden: "_before". Ein weiteres Beispiel für einen nützlichen Hook wäre zudem "_reconfigure". Dieser kann während der Ausführung der Tests Einstellungen in den Konfigurations-Dateien ändern und diese nach Ausführung des Tests wieder rückgängig machen.

Wie weiter oben schon erwähnt, bringt jeder Webdriver vorgefertigte Funktionen mit. Beispiele für diese wären "fillField()", womit ein Input-Feld ausgefüllt werden kann, die Funktion "click()", die einen Klick auf einen Button ausführt oder "seeElement()", womit überprüft werden kann, ob ein bestimmtes Element auf der Seite vorhanden und sichtbar ist. Es gibt allerdings auch komplexere Funktionen wie z. B. "executeJS()", welche eine JavaScript-Funktion ausführt, "seeInDatabase", welche nach einem Eintrag in der Datenbank sucht, "waitForElementChange()", welche bis zu einem festgelegten Timeout auf eine Änderung an einem Element wartet oder "seeResponseContainsJson()", die prüft, ob eine Antwort im JSON-Format erfolgt und ob Struktur und Inhalt der gewünschten Vorgabe entsprechen.

Aufgrund der umfangreichen Möglichkeiten, die Codeception bietet, lässt es sich auch für andere Verwendungszwecke einsetzen als nur zum Testen. Funktionen wie "grabTextFrom()", die Daten auf einer Website suchen und wiederverwenden, ermöglichen es, z. B. einen Bot zu schreiben, der automatisch bestimmte Aktionen in einem Browsergame für einen übernimmt oder den Stand einer Aktie beobachtet.

Eigene Erfahrungen

Wir haben Codeception in mehreren Projekten zum Testen eingesetzt und haben damit gute Erfahrungen gemacht. Die Vorbereitung für das Testen und das Schreiben der eigentlichen Tests ist einfach und mit etwas Übung auch recht schell erledigt. Wie schon weiter oben erwähnt, sind die Tests auch für andere lesbar, die nicht am Testen beteiligt waren, was sich als praktisch erweist. Da beim Fehlschlagen eines Tests sowohl ein Screenshot als auch der HTML-Code der Seite gespeichert wird und Fehlermeldungen ausgegeben werden (Vom Server, Client und Browser), ist die anschließende Fehlerbehebung auch problemlos möglich, wenn man den Tests nicht zugeschaut hat.

Es sollte allerdings beachtet werden, dass sich der Zeitaufwand meistens nur lohnt, wenn die Tests oft gebraucht werden (z. B. nach jedem Update). Codeception aufzusetzen, Page's zu erstellen, dafür die Locators (Frage) geeigneten Selectors herauszusuchen und die eigentlichen Tests zu schreiben ist zwar nicht schwer, kostet aber trotzdem etwas Zeit. Wer beispielsweise nach Fertigstellung einer Website nur einmal überprüfen möchte, ob alle Elemente vorhanden sind und ob alle Weiterleitungen funktionieren, der ist wahrscheinlich schneller, wenn er es von Hand prüft.

Ein paar nützliche Links zum Thema: