PHP-Applikationen mit Cucumber testen
Posted by in Agile MethodenUser Acceptance Tests (UAT) oder auf Deutsch “Akzeptanztests” sind eine wichtige Komponente in der Testgetriebenen Entwicklung. Bisher kannte ich die üblichen Verdächtigen, also Selenium. Man kann damit komfortabel einen Klickpfad definieren, PHP-Code exportieren und daraus einen Test für PHPUnit erzeugen. Leider benötigen diese Tests immer einen laufenden Seleniumdienst, einen Browser und diesen ganzen Kram. Ich bin eher ein Fan von Testmethoden die headless funktionieren, direkt auf einer Shell. Bei meinem Blick über den Tellerrand in Richtung Ruby On Rails bin ich auf Cucumber aufmerksam geworden. Cucumber ist ein tolles Test-Framework für Behaviour Driven Development, das mit menschenlesbaren Tests im Klartext arbeitet. Zusammen mit Webrat, einem Toolkit um Webbrowser fernzusteuern oder mit Mechanize komplett headless zu arbeiten, kann man Webapplikationen hervorragend testen.
Am Beispiel der Google-Suche werde ich zeigen, wie einfach man Tests mit Cucumber anlegen kann und das Testen damit wirklich Spaß macht :-)
Die Installation von Cucumber ist denkbar einfach. Als Basis benötigen wir eine lauffähige Ruby Umgebung. Wie man die einrichtet findet man zur genüge im Netz. Die glücklichen Mac Benutzer unter uns können sich an dieser Stelle ins gemachte Nest setzen, hier wird alles ab Werk mitgeliefert. Cucumber, Webrat und Mechanize können wir ganz einfach mit gem, dem Paketmanager von Ruby, installieren:
sudo gem install cucumber sudo gem install webrat sudo gem install mechanize
Jetzt erstellen wir die Verzeichnisstruktur für die Cucumber Tests, sowie 3 leere Dateien:
mkdir tests mkdir tests/features mkdir tests/features/support mkdir tests/features/step_definitions touch tests/features/search.feature touch tests/features/support/env.rb touch tests/features/step_definitions/search_steps.rb

Zuerst definieren wir das Environment für die Cucumber Tests. Wir laden im Prinzip Webrat und sagen Webrat das er “mechanize” benutzen soll, um die Webseiten zu rendern. Die Datei tests/features/support/env.rb füllen wir also mit folgendem Inhalt:
require 'webrat' Webrat.configure do |config| config.mode = :mechanize end World(Webrat::Methods) World(Webrat::Matchers)
Jetzt schreiben wir unser erstes Testszenario, eine einfache Suche, in die Datei tests/features/search.feature:
Feature: Search
In order to find information
As an user
I want to use the search function
Scenario: Simple search and check for result
Given I am on the Google search page
When I search for "car"
Then I should see "car" in the search resultsNun rufen wir Cucumber auf um zu sehen, was es von unserem Szenario hält:
cd tests cucumber
Jetzt sagt uns Cucumber das es undefinierte Schritte gibt und schlägt uns ein Gerüst vor, um diese Schritte einfach implementieren zu können:

Dieses Gerüst kopieren wir einfach 1:1 in die Datei tests/features/step_definitions/search_steps.rb:
Given /^I am on the Google search page$/ do pending # express the regexp above with the code you wish you had end When /^I search for "([^"]*)"$/ do |arg1| pending # express the regexp above with the code you wish you had end Then /^I should see "([^"]*)" in the search results$/ do |arg1| pending # express the regexp above with the code you wish you had end
Nun führen wir Cucumber erneut aus:

Nun weist Cucumber uns darauf hin das es noch Schritte gibt, die wir noch nicht implementiert haben. Im folgenden implementieren wir Schritt für Schritt die fehlenden Schritte. Zuerst das Öffnen der Webseite. Dazu ersetzen wir in Zeile 2 das “pending” durch die Zeile:
visit "http://www.google.de"
Nun führen wir Cucumber erneut aus, um zu sehen ob der Schritt funktioniert:

Hervorragend! Ein Schritt ist grün, wir haben noch zwei vor uns. Jetzt füllen wir das Imput-Feld mit dem Namen “q” mit unserem Suchberiff und klicken auf den Button mit dem Namen “Google-Suche”. Dazu ersetzen wir ab Zeile 7 das “pending” durch folgende Zeilen:
fill_in "q", :with => arg1 click_button "Google-Suche"
Nun führen wir Cucumber erneut aus:

Jetzt implementieren wir den letzten Schritt. Wir überprüfen ob wir mindestens einen Suchtreffer zu “car” haben. In der Ergebnisseite suchen wir also in allen Div’s der Klasse “s” nach Em-Tags mit dem Inhalt “car”. Der letzte Schritt lautet also wie folgt:
response_body.should have_selector('div.s em') do |em|
em.should contain(arg1)
endDas Gesamtkunstwerk sieht jetzt also so aus:
Given /^I am on the Google search page$/ do
visit "http://www.google.de"
end
When /^I search for "([^"]*)"$/ do |arg1|
fill_in "q", :with => arg1
click_button "Google-Suche"
end
Then /^I should see "([^"]*)" in the search results$/ do |arg1|
response_body.should have_selector('div.r em') do |em|
em.should contain(arg1)
end
end
Nun rufen wir wieder Cucumber auf:

Jetzt habe ich unerwarteterweise einen Fehler bekommen. Die Ursache liegt in einem 302-Redirect. Es kommt einfach kein Suchergebnis.
Ich hätte diesen kleinen Ausflug in die Welt von Cucumber natürlich gerne mit einem “grünen” Testlauf abgeschlossen, aber ich hoffe das ich trotzdem ein wenig Neugierde bei dem ein oder anderen wecken konnte.
In den nächsten Wochen werde ich noch weitere Beispiel-Szenarien veröffentlichen, also schön am Ball bleiben :-)
Viel Spaß beim Ausprobieren!
You can follow any responses to this entry through the RSS 2.0 You can leave a response, or trackback.



Pingback: Web-Rocker’s Showdown : Gjero Krsteski
Pingback: Using Cucumber with PHP and without Ruby on Rails » JerryWho
Hallo,
wo sind die neue Beispiel-Szenarien?
Grüße,
Artem
Wenn ich click_button “button_name” verwende, kriege ich diese Fehlermeldung:
422 => (Mechanize::ResponseCodeError)
Wie kann ich dieses Problem lösen?