PHPUnit mit Selenium

by mlaug on 26. September 2010

Häufig steht man bei der Entwicklung vor der Frage, wie sich die eigene Software eigentlich verhält, wenn mehr als nur man selber diese benutzen möchte. Gerade junge Internetinnovationen wie Twitter haben stark mit ihrer Architektur zu kämpfen, nachdem Millionen von Benutzer diese verwendet haben. Die allgemeingültige Lösung ist meist immer die Erweiterung des Hardware Pools. Doch manchmal ist auch ganz ratsam und auch interessant herauszufinden, wo genau sich der Flaschenhals einer Software genau versteckt. Hierfür sind Lasttest sehr gut geeignet.

Im Netz finden sich viele Tools, wobei die meisten kostenpflichtig sind, wie z.B. ein Tool von Neotys. Mit ein wenig Aufwand lassen die sich Grundlegende Lasttests jedoch auch ohne Softwarekosten bewerkstelligen.

In meinem Fall versuche ich einen Testcase mit PHP und Selenium aufzubauen.

Was ist Selenium?

Hinter Selenium versteckt sich ein Plugin für den Firefox. Dieses ermöglicht es einem Entwickler seine Bewegungen durch eine Webseite aufzunehmen und diese dann automatisiert als Testcase abspielen zu lassen. Problem dabei ist, dass man erneut wieder auf einen Browser beschränkt ist. Von einem Lasttest hat das noch nicht viel. Hier kommt Selenium Grid zum Einsatz

Was ist Selenium Grid?

Hierbei handelt es sich um eine in Java programmierten Distributions Server für Selenium. Er ermöglicht es Testcases parallel in unterschiedlichen Umgebungen zu starten. Hier liegt die wahre Kraft von Selenium und eine echte Möglichkeit reale Lasttests zu entwickeln. Dabei können auch mehr als ein Rechner parallel an diesen Grid über die später erwähnten Konsolen angeschlossen werden.

Installation von Selenium Grid (1.0.8)

Nach dem Download sollte man überprüfen, ob das System für die Verwendung des Selenium Grids ausgestattet ist

Da MacOS von Haus aus mit Ant ausgeliefert wird, müssen wir hier keine Änderungen mehr vornehmen. Wenn jetzt auch mindestens Java in der Version > 1.5 installiert ist, muss der Server nur noch gestartet werden. Die Anweisung dafür findet ihr am Ende des gerade ausgeführten Tests (‘ant launch-hub’ und ‘ant launch-remote-control’)

Hinweis: Sollte es hier zu Problemen kommen, läuft wahrscheinlich eine NetBeans Instanz, die bereits das Selenium Plugin installiert hat. Hier läuft bereits ein Selenium Server auf dem Port 4444.

Solltet ihr weiterhin auf MacOS 10.6 setzen, könnt ihr das aktuelle NetBeans Plugin “beinahe” vergessen. Der mitgelieferte Server hat noch einen Bug, der daraus resultiert, dass die firefox.sh und nicht firefox-bin aufgerufen wird. Dies hat zur Folge, dass keine Browser Instanz erzeugt werden kann, da die falsche SQLLite Lib verwendet wird. Mehr dazu findet ihr dem Bericht zum Bug

Das Problem könnt ihr umgehen, in dem ihr von der runtergeladenen Version den Standalone Server startet und den in Netbeans deaktiviert.

Testen Testen Testen

Netbeans liefert wie bereits erwähnt ein Plugin, womit sich relativ komfortabel Testcases erstellt werden können. Dazu kann man einfach dem Wizard folgen und hat anschließend seinen ersten Rumpf für einen Testcase. Die Klasse, die hier erstellt wird, erbt von PHPUnit_Extensions_SeleniumTestCase und stellt eine Menge weiterer Methoden zur Verfügung. Im Allgemeinen halten sich die Methoden jedoch an die Funktionen, die man im Firefox Plugin auswählen kann. So findet man sich eigentlich relativ schnell zurecht. Aber um effektiv an unsere Testcases zu kommen benutzen wir die Export Funktionen des Firefox Plugins.

Bauen wir doch einfach mal ein Beispiel, in dem wir auf simpelste Art und Weise die rudimentärste Funktionalität der Seite von yourdelivery testen.

Hinweis: Es gelten die gleichen Voraussetzungen wie bei üblichen PHPUnit Testcases, d.h. Phpunit sollte auf dem System installiert sein!

require_once 'PHPUnit/Extensions/SeleniumTestCase.php';

class Restaurant extends PHPUnit_Extensions_SeleniumTestCase {

    function setUp() {
        $this->setBrowser("*chrome");
        $this->setBrowserUrl("http://www.yourdelivery.de");
    }

    function testMyTestCase() {
        $this->open('/');
        $this->type('plz','10627');
        $this->click('yd-start-order');
        $this->waitForPageToLoad('30000');
        $this->assertTrue($this->isTextPresent('Da Giorgio'));
    }
}

Diesen Test kann man nun bereits im NetBeans realisiert werden. Wundert euch nicht, wenn während des Testcases der Firefox in eurem Dashboard permanent erscheint und verschwindet. Dies ist ein Indiz für die Instanzen, die während des Testcases erstellt werden.

Wunderbar, wir haben unseren ersten Testcase erstellt und diesen zum laufen gebracht. Unser Ziel ist es jedoch einen Lasttest auf unserem System zu ermöglichen. Das schaffen wir nur, wenn die Testcases mehrmals hintereinander und auch parallel ausgeführt werden. Hierbei unterstützt uns der Grid von Selenium. Mit diesem ist es möglich Testcases parallel auszuführen um so den gewünschten Effekt zu erreichen.

Konfiguration des Lasttest

Um einen Lasttest zu erstellen, sollten unsere Test parallel laufen. Um die zu ermöglichen setzen wir auf den Grid von Selenium. Dazu starten wir zum einen den Hub und fügen so viele Instanzen hinzu, wie wir mögen. Mindestens genau so häufig oder am besten mehrmals kopiert man den bereits erstellten Testcase und benennt diesen um.

[console1] ant launch-hub
[console2] ant -Dport=4445 launch-remote-control -Denvironment="*chrome"
[console3] ant -Dport=4446 launch-remote-control -Denvironment="*firefix"
[consoleX] ant -DPort=4444+x launch-remote-control

Leider habe ich in diesem Punkt erfahren müssen, dass PHP (welch überraschung) seine Testcases nicht parallel ausführen kann. Daher muss man hier auf JUnit setzen. Ich werde mich damit in einem späteren Artikel befassen. In dem Zusammenhang auch mit Continous Testing und Hudson.

Das fehlen von Threads in PHP ist manchmal wirklich ein Manko…

Leave a Comment