Achtung:
Diese Webseite betrachtet nur das mittlerweile veraltete Selenium 1 (RC).
Für neue Projekte sollten Sie nur den Nachfolger Selenium 2 (WebDriver) verwenden.
Mit Selenium können Sie über automatisierte Integrationstests Webanwendungen über einen Webbrowser testen. Dies hat den Vorteil, dass JavaScript und Ajax leichter und realitätsnäher getestet werden. Allerdings gibt es auch einen Nachteil: Da die Installation eines Webbrowsers vorausgesetzt wird, ist die Ausführung auf beliebigen PCs und Betriebssystemen nicht mehr so einfach zu gewährleisten und die Ausführung in Continuous-Integration-Systemen könnte unsicherer sein. Falls Sie nur einfache HTML-Anwendungen ohne DHTML, JavaScript und Ajax testen wollen, können HtmlUnit und HttpUnit besser geeignet sein.
Der folgende Text beschreibt weder die Möglichkeiten von Selenium noch von Maven. Stattdessen werden einige mögliche Maven-Konfigurationen für Selenium-1-Tests gezeigt.
Bitte beachten Sie die drei grundsätzlich verschiedenen Selenium-Versionen:
Selenium 1, auch Selenium RC (Remote Control) genannt:
Selenium 1 (RC) ist der Vorgänger von Selenium 2 (WebDriver) und sollte möglichst nicht mehr für neue Anwendungen verwendet werden. Selenium 1 (RC) basiert auf der Verwendung eines für den Test gestarteten Proxy-Servers (Selenium-Server), welcher den gewünschten Webbrowser bedient. Die Testprogrammierung beginnt typischerweise mit zwei Zeilen ähnlich zu:
Selenium selenium = new DefaultSelenium( "localhost", 4444, "*firefox", "http://www.meintesthost.de" ); selenium.start();
Siehe: Selenium 1 (Selenium RC) und Migrating From Selenium RC to Selenium WebDriver.
Selenium 2, auch Selenium WebDriver genannt:
Anders als Selenium 1 verwendet Selenium 2 (WebDriver) keinen Proxy-Server, sondern spricht den gewünschten Webbrowser direkt an, über browserspezifische WebDriver. Beispielsweise für den Firefox-Webbrowser könnte das Testprogramm mit einer Zeile beginnen ähnlich zu:
WebDriver webDriver = new FirefoxDriver();
Siehe: Selenium WebDriver, Selenium-Doku und Selenium-WebDriver-Programmierbeispiel.
Selenium 2 (WebDriver) bietet ein neues und verbessertes Programmier-API. Für Migrationszwecke kann aber auch in Selenium 2 auf viele Funktionen des alten Selenium-1-Programmier-APIs zurückgegriffen werden, indem folgendermaßen das alte Selenium-Objekt erzeugt wird:
Selenium selenium = new WebDriverBackedSelenium( webDriver, "http://www.meintesthost.de" );
Selenium IDE:
Selenium IDE ist eine Erweiterung (Plug-in) für den Firefox-Webbrowser, womit schnell und einfach im Firefox-Webbrowser ablauffähige Skripte zu Benutzerinteraktionen erstellt und abgespielt werden können (record-and-playback), beispielsweise zum Reproduzieren von Fehlersituationen oder zur Vorbereitung von automatisierten Tests (Prototyping). Die mit Selenium IDE generierbaren Skripte sind nicht für Integrations- und Regressionstests vorgesehen, wo hohe Stabilität und Reproduzierbarkeit wichtig ist.
Siehe: Selenium IDE Übersicht und Selenium IDE Doku.
Das folgende Beispiel zeigt für den Firefox-Webbrowser, wie in einer Selenium-WebDriver-Anwendung das alte Selenium-1-Programmier-API verwendet werden kann. Dies sollte nicht für neue Anwendungen verwendet werden, aber kann zur Migration auf Selenium 2 sinnvoll sein.
Sehen Sie sich die Selenium-Doku und das WebDriver-Interface an.
Legen Sie ein neues Projekt an:
cd \MeinWorkspace
md SeleniumWebDriverBacked
cd SeleniumWebDriverBacked
md src\test\java\integrationtest
Erzeugen Sie im Projektverzeichnis die Projektkonfiguration: pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>SeleniumWebDriverBacked</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>SeleniumWebDriverBacked</name> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>2.47.1</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> </project>
Erzeugen Sie im src\test\java\integrationtest-Verzeichnis die Testklasse: WebDriverBackedSeleniumTest.java
package integrationtest; import org.junit.*; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import com.thoughtworks.selenium.Selenium; import com.thoughtworks.selenium.webdriven.WebDriverBackedSelenium; public class WebDriverBackedSeleniumTest { @Test public void testWebDriverBackedSelenium() { // WebDriver-Klasse aus Selenium 2: WebDriver webDriver = new FirefoxDriver(); // Selenium-Klasse aus Selenium 1: Selenium selenium = new WebDriverBackedSelenium( webDriver, "http://www.google.de" ); try { selenium.open( "" ); selenium.waitForPageToLoad( "33000" ); selenium.type( "q", "seleniumhq.org" ); selenium.click( "btnG" ); selenium.waitForCondition( "selenium.isTextPresent( 'seleniumhq.org' )", "22000" ); Assert.assertTrue( selenium.isTextPresent( "seleniumhq.org" ) ); } finally { selenium.stop(); } } }
Der Test startet einen WebDriver, erzeugt ein WebDriverBackedSelenium, öffnet die Google-Startseite in selenium.open(), trägt in das das Input-Textfeld "q" den Suchbegriff "seleniumhq.org" ein, klickt den Button "btnG" und überprüft die Ergebnis-Webseite.
Die Projektstruktur sieht jetzt so aus (überprüfen Sie es mit tree /F):
[\MeinWorkspace\SeleniumWebDriverBacked] |- [src] | '- [test] | '- [java] | '- [integrationtest] | '- WebDriverBackedSeleniumTest.java '- pom.xml
Starten Sie den Test:
cd \MeinWorkspace\SeleniumWebDriverBacked
mvn clean test
Dieses Beispiel zeigt eine sehr minimalistische Version eines Selenium-1-Tests, um das Prinzip zu verdeutlichen. In späteren Beispielen folgen Verbesserungen.
Sie können dieses und die meisten der folgenden Programmierbeispiele wahlweise downloaden oder, wie im Folgenden beschrieben wird, schrittweise ausführen.
Legen Sie in Ihrem Projekte-Workspace-Verzeichnis (z.B. \MeinWorkspace) das neue Projekt SeleniumGoogleSimple an:
cd \MeinWorkspace
md SeleniumGoogleSimple
cd SeleniumGoogleSimple
md src\test\java\seleniumtest
Erzeugen Sie im SeleniumGoogleSimple-Projektverzeichnis die Maven-Projektkonfiguration: pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>SeleniumGoogleSimple</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>SeleniumGoogleSimple</name> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>selenium-maven-plugin</artifactId> <version>2.3</version> <executions> <execution> <phase>test-compile</phase> <goals> <goal>start-server</goal> </goals> <configuration> <background>true</background> </configuration> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>2.24.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-server</artifactId> <version>2.24.1</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> </dependencies> </project>
Sehen Sie sich die Doku zum Selenium-Maven-Plugin und zum start-server-Goal an.
Erzeugen Sie im src\test\java\seleniumtest-Verzeichnis die Testklasse: GoogleSeleniumTest.java
package seleniumtest; import com.thoughtworks.selenium.*; import junit.framework.TestCase; public class GoogleSeleniumTest extends TestCase { private Selenium selenium; public void setUp() { // Bitte anpassen, falls nicht Firefox verwendet werden soll: selenium = new DefaultSelenium( "localhost", 4444, "*firefox", "http://www.google.de" ); selenium.start(); selenium.setSpeed( "500" ); } public void tearDown() { selenium.stop(); } public void testGoogle() { selenium.open( "" ); selenium.waitForPageToLoad( "33000" ); selenium.type( "q", "seleniumhq.org" ); selenium.click( "btnG" ); selenium.waitForCondition( "selenium.isTextPresent( 'seleniumhq.org' )", "22000" ); assertTrue( selenium.isTextPresent( "seleniumhq.org" ) ); } }
In setUp() wird Selenium gestartet und in testGoogle() wird die Google-Webseite geöffnet, im Eingabefeld etwas eingetragen, der Such-Button betätigt und kontrolliert, ob ein bestimmter Text in der Ergebnisseite enthalten ist. Das "selenium.setSpeed( "500" )"-Kommando dient nur zur Verlangsamung des Tests, damit der Ablauf besser beobachtet werden kann. Sehen Sie sich die vielfältigen Möglichkeiten an, welche die Selenium-Klasse bietet.
Falls Sie nicht Mozilla Firefox installiert haben, müssen Sie in der setUp()-Methode beim DefaultSelenium-Konstruktor einen anderen Browser vorgeben (für den Microsoft Internet Explorer z.B. *iexplore oder besser *iexploreproxy, siehe hierzu die Selenium-RC-Doku) (die anschließend folgenden Beispiele zeigen, wie dies per Kommandozeile umschaltbar gemacht werden kann).
Die Projektstruktur sieht jetzt so aus (überprüfen Sie es mit tree /F):
[\MeinWorkspace\SeleniumGoogleSimple] |- [src] | '- [test] | '- [java] | '- [seleniumtest] | '- GoogleSeleniumTest.java '- pom.xml
Schließen Sie den Webbrowser und führen Sie den Test aus:
cd \MeinWorkspace\SeleniumGoogleSimple
mvn test
Sie können im Webbrowser den Verlauf des Tests verfolgen und erhalten im Kommandozeilenfenster:
Launching Selenium Server ... INFO [org.openqa.jetty.http.HttpServer] Version Jetty/5.1.x ... Selenium Server started ... ------------------------------------------------------- T E S T S ------------------------------------------------------- Running seleniumtest.GoogleSeleniumTest ... INFO - Command request: getNewBrowserSession[*firefox, http://www.google.de, ] ... ... INFO - Launching Firefox... ... INFO - Got result: OK,true ... ... INFO - Killing Firefox... ... Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
Falls Sie eine der beiden folgenden Fehlermeldung erhalten:
BUILD ERROR Failed to resolve artifact. Missing: org.seleniumhq.selenium:selenium-server:jar:2.24.1
BUILD ERROR Failed to resolve artifact. Missing: org.seleniumhq.selenium.server:selenium-server:jar:standalone:1.0.2
Prüfen Sie, ob Ihr Virenscanner den Download von selenium-server-1.0.2-standalone.jar bzw. selenium-server-2.24.1.jar geblockt hat, weil er die darin enthaltene Datei "hudsuckr.exe" für zu gefährlich hält. In diesem Fall müssen Sie die Datei manuell downloaden oder im Virenscanner hierfür eine Ausnahme konfigurieren oder den Virenscanner kurzeitig temporär deaktivieren.
Falls Sie folgende Fehlermeldung erhalten:
Failed to start new browser session: Firefox could not be found in the path!
Please add the directory containing ''firefox.exe'' to your PATH environment variable
Dann erweitern Sie (vorübergehend) die PATH-Umgebungsvariable, zum Beispiel für den 32-bit-Firefox unter 64-bit-Windows:
set PATH=%PATH%;C:\Program Files (x86)\Mozilla Firefox
mvn test
Wenn Sie sich in einem Proxy-geschützten Firmennetz befinden, kann der Test fehlschlagen. Sehen Sie sich in diesem Fall die weiter unten beschriebenen Selenium-Tests an, welche von einer eigenen Webanwendung erzeugte Webseiten testet (was ja auch der typischere Fall für Selenium-Tests ist).
Wir wollen für das letzte Beispiel kleine Verbesserungen durchführen:
Führen Sie folgende Schritte durch:
Legen Sie ein neues Projekt an:
cd \MeinWorkspace
md SeleniumGoogleJavaIntegrTest
cd SeleniumGoogleJavaIntegrTest
md src\test\java\integrationtest
Erzeugen Sie im Projektverzeichnis die die Maven-Projektkonfiguration: pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>SeleniumGoogleJavaIntegrTest</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>SeleniumGoogleJavaIntegrTest</name> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>selenium-maven-plugin</artifactId> <version>2.3</version> <executions> <execution> <phase>pre-integration-test</phase> <goals> <goal>start-server</goal> </goals> <configuration> <background>true</background> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.12</version> <configuration> <skip>true</skip> <systemPropertyVariables> <browser>firefox</browser> </systemPropertyVariables> </configuration> <executions> <execution> <phase>integration-test</phase> <goals> <goal>test</goal> </goals> <configuration> <skip>false</skip> </configuration> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>2.24.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-server</artifactId> <version>2.24.1</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> </dependencies> </project>
Sehen Sie sich die Doku zum Surefire-Plugin, zum Selenium-Plugin und zum start-server-Goal an.
Erzeugen Sie im src\test\java\integrationtest-Verzeichnis die Testklasse: GoogleSeleniumTest.java
package integrationtest; import org.junit.*; import com.thoughtworks.selenium.*; public class GoogleSeleniumTest { private static Selenium selenium; @BeforeClass public static void startSelenium() { String browser = System.getProperty( "browser" ); selenium = new DefaultSelenium( "localhost", 4444, "*" + browser, "http://www.google.de" ); selenium.start(); selenium.setSpeed( "500" ); } @AfterClass public static void stopSelenium() { selenium.stop(); } @Test public void testGoogle() { selenium.open( "" ); selenium.waitForPageToLoad( "33000" ); selenium.type( "q", "seleniumhq.org" ); selenium.click( "btnG" ); selenium.waitForCondition( "selenium.isTextPresent( 'seleniumhq.org' )", "22000" ); Assert.assertTrue( selenium.isTextPresent( "seleniumhq.org" ) ); } }
Der Test startet Selenium in startSelenium(). In testGoogle() wird wieder die Google-Webseite geöffnet, im Eingabefeld etwas eingetragen, der Such-Button betätigt und kontrolliert, ob ein bestimmter Text in der Ergebnisseite enthalten ist.
Bitte beachten Sie, dass der Webbrowser diesmal nicht fest programmiert ist, sondern als browser-Parameter übergeben wird.
Die Projektstruktur sieht jetzt so aus (überprüfen Sie es mit tree /F):
[\MeinWorkspace\SeleniumGoogleJavaIntegrTest] |- [src] | '- [test] | '- [java] | '- [integrationtest] | '- GoogleSeleniumTest.java '- pom.xml
Schließen Sie den Webbrowser und starten Sie den Selenium-Integrationstest:
cd \MeinWorkspace\SeleniumGoogleJavaIntegrTest
mvn verify
Falls Sie Mozilla Firefox installiert haben, können Sie wieder den Verlauf des Tests im Webbrowser verfolgen und erhalten wieder im Kommandozeilenfenster:
Launching Selenium Server ... INFO - Launching Firefox... ... Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] BUILD SUCCESS
Dasselbe Ergebnis erhalten Sie, wenn Sie Firefox explizit angeben:
mvn verify -Dbrowser=firefox
Starten Sie den Test mit fehlerhaftem Browserparameter:
mvn verify -Dbrowser=?
Sie erhalten eine Fehlermeldung und unter "Supported browsers" eine Liste der unterstützten Browser.
Falls Sie unter Windows arbeiten: Führen Sie den Integrationstest für den Microsoft Internet Explorer aus:
mvn verify -Dbrowser=iexploreproxy
Falls Sie über einen Proxy-Server ins Internet gelangen, sollten Sie sich vor diesem Aufruf die Proxy-Einstellungen merken,
weil es vorkommen kann, dass diese Einstellungen bei dem Test verloren gehen und anschließend wiederhergestellt werden müssen.
Sie finden die Proxy-Einstellungen unter:
Start | Systemsteuerung | Netzwerk und Internet | Internetoptionen | Reiter Verbindungen | LAN-Einstellungen.
Oder alternativ im Microsoft Internet Explorer unter:
Extras | Internetoptionen | Reiter Verbindungen | LAN-Einstellungen.
Falls es zu Problemen kommt, testen Sie die verschiedenen "Run Modes" iexplore und iexploreproxy. Eventuell müssen Sie auch Sicherheits- und Pop-up-Blocker-Einstellungen ändern. Sehen Sie sich auch die Selenium-RC-Doku an.
Auch hier gilt wieder: Wenn Sie sich in einem Proxy-geschützten Firmennetz befinden, kann der Test fehlschlagen. Sehen Sie sich in diesem Fall die weiter unten beschriebenen Selenium-Tests an, welche von einer eigenen Webanwendung erzeugte Webseiten testet.
Bei den bisherigen Beispielen war der Testablauf als Java-Sourcecode formuliert. In diesem Beispiel wird der Testablauf stattdessen in HTML-Tabellen definiert (in etwa vergleichbar mit dem Fit-ActionFixture).
Legen Sie ein neues Projekt an:
cd \MeinWorkspace
md SeleniumGoogleHtmlIntegrTest
cd SeleniumGoogleHtmlIntegrTest
md src\test\selenium
Erzeugen Sie im Projektverzeichnis die die Maven-Projektkonfiguration: pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>SeleniumGoogleHtmlIntegrTest</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>SeleniumGoogleHtmlIntegrTest</name> <properties> <browser>firefox</browser> </properties> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>selenium-maven-plugin</artifactId> <version>2.3</version> <configuration> <browser>*${browser}</browser> <suite>src/test/selenium/suite.html</suite> <startURL>http://www.google.de</startURL> </configuration> <executions> <execution> <phase>integration-test</phase> <goals> <goal>selenese</goal> </goals> <configuration> <background>true</background> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
Sehen Sie sich die Doku zum Selenium-Maven-Plugin und zum selenese-Goal an.
Erzeugen Sie im src\test\selenium-Verzeichnis folgende HTML-Dateien:
suite.html
<html> <head><title>SeleniumGoogleHtmlIntegrTest</title></head> <body> <table> <tr><td><b>SeleniumGoogleHtmlIntegrTest</b></td></tr> <tr><td><a href="./GoogleTest1.html">GoogleTest1</a></td></tr> <tr><td><a href="./GoogleTest2.html">GoogleTest2</a></td></tr> </table> </body> </html>
GoogleTest1.html
<html> <head><title>GoogleTest1</title></head> <body> <table cellpadding="2" cellspacing="0" border="1"> <tr><td rowspan="1" colspan="3">GoogleTest1</td></tr> <tr><td>setSpeed </td><td>1000 </td><td></td></tr> <tr><td>open </td><td> </td><td></td></tr> <tr><td>type </td><td>q </td><td>seleniumhq.org</td></tr> <tr><td>click </td><td>btnG </td><td></td></tr> <tr><td>verifyTextPresent</td><td>seleniumhq.org</td><td></td></tr> </table> </body> </html>
GoogleTest2.html
<html> <head><title>GoogleTest2</title></head> <body> <table cellpadding="2" cellspacing="0" border="1"> <tr><td rowspan="1" colspan="3">GoogleTest2</td></tr> <tr><td>setSpeed </td><td>1000 </td><td></td></tr> <tr><td>open </td><td> </td><td></td></tr> <tr><td>type </td><td>q </td><td>selenium-maven-plugin selenese</td></tr> <tr><td>click </td><td>btnG </td><td></td></tr> <tr><td>assertTextPresent</td><td>mojo.codehaus.org</td><td></td></tr> </table> </body> </html>
suite.html fasst die Selenium-Tests zu einer Selenium-Suite zusammen.
Die beiden GoogleTest*.html-Dateien enthalten die Testbeschreibungen: Diesmal nicht als Java-Code, sondern als HTML-Tabelle.
Die Tests öffnen die Google-Webseite, tragen im Eingabefeld etwas ein, betätigen den Such-Button und kontrollieren, ob ein bestimmter Text in der Ergebnisseite enthalten ist.
Das "setSpeed 1000"-Kommando dient nur zur Verlangsamung des Tests, damit der Ablauf besser beobachtet werden kann.
Sehen Sie sich die vielfältigen
Selenium Commands an.
Die Projektstruktur sieht jetzt so aus (überprüfen Sie es mit tree /F):
[\MeinWorkspace\SeleniumGoogleHtmlIntegrTest] |- [src] | '- [test] | '- [selenium] | |- GoogleTest1.html | |- GoogleTest2.html | '- suite.html '- pom.xml
Starten Sie den Selenium-Integrationstest:
cd \MeinWorkspace\SeleniumGoogleHtmlIntegrTest
mvn verify
Sie erhalten in target\results-firefox-suite.html:
Test suite results
|
Im Fehlerfall würden Sie beispielsweise erhalten:
...
|
In den letzten Beispielen wurden die Testskripte manuell erstellt, entweder als Java-Sourcecode oder als HTML-Tabelle. Meistens ist es einfacher, stattdessen die Testskripte ähnlich wie bei einem Makrorekorder "aufzunehmen". Dies ist sehr komfortabel mit Selenium IDE möglich.
Selenium IDE setzt Mozilla Firefox voraus. Die erstellten Skripte können mit beliebigen Browsern abgespielt werden.
Installieren Sie das Firefox-Plug-in Selenium IDE (z.B. selenium-ide-1.2.0.xpi) von http://seleniumhq.org/download/ in Firefox.
Starten Sie Firefox. Starten Sie Selenium IDE in Firefox über "Extras" | "Selenium IDE". Selenium IDE startet in einem Extrafenster.
Öfnen Sie im ursprünglichen Firefox-Fenster eine beliebige Webseite. Tragen Sie Texte in Eingabefelder ein und klicken Sie auf Buttons und Links. Im Selenium-IDE-Fenster erscheinen alle Kommandos.
Um dem Testskript Überprüfungen hinzuzufügen, klicken Sie auf der Webseite mit der rechten Maustaste auf Elemente oder markieren Textbereiche und klicken darauf mit der rechten Maustaste. Es erscheint ein Kontextmenü. Darin finden Sie im unteren Bereich die zum jeweiligen Element passenden üblichen Kommandos (z.B. assert... und verify...). Ganz unten finden Sie "Show All Available Commands". Wählen Sie ein Kommando aus, damit es dem Testskript im Selenium-IDE-Fenster hinzugefügt wird.
Wenn Sie fertig sind, klicken Sie im Selenium-IDE-Fenster oben rechts auf den roten Button "Click to Stop Recording".
Klicken Sie im Selenium-IDE-Fenster oben auf einen der beiden grünen dreieckigen Abspiel-Buttons "Play test suite/case", um das Skript ablaufen zu lassen. Wenn Sie kurz nach dem Start auf den gelben "Pause"-Button klicken, können Sie das Skript über den blauen Pfeil-Button "Step" auch in Einzelschritten durchlaufen.
Unter dem Tabulatorreiter "Source" können Sie sich das Testskript als HTML-Source ansehen.
Speichern Sie im Selenium-IDE-Fenster das Testskript über "Datei" | "Export Test Case As...". Sie können im HTML-Format, als Java-Sourcecode ("JUnit") und in anderen Formaten speichern.
Die gespeicherten Fragmente können Sie nach kleinen Anpassungen leicht in die obigen Programmierbeispiele einfügen.
In den bisherigen Beispielen wurde immer eine Remote-Webanwendung getestet, die nicht vom eigenen Projektmodul erzeugt wurde, und die bereits aktiv ist. Das muss nicht unbedingt eine entfernte Webanwendung (wie z.B. Google) sein, sondern kann auch eine auf dem lokalen PC laufende sein.
In den folgenden Beispielen ist die Webanwendung Teil desselben Maven-Projektmoduls und kann innerhalb des Integrationstests automatisch erzeugt, deployt und getestet werden, inklusive Hoch- und Runterfahren eines geeigneten Testservers.
Öffnen Sie ein Kommandozeilenfenster, wechseln Sie in Ihr Projekte-Workspace-Verzeichnis (z.B. \MeinWorkspace) und erzeugen Sie eine Webapp-Projektstruktur:
cd \MeinWorkspace
mvn archetype:generate -DinteractiveMode=false -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=de.meinefirma.meinprojekt -DartifactId=SeleniumJetty
cd SeleniumJetty
md src\main\java\de\meinefirma\meinprojekt
md src\test\java\de\meinefirma\meinprojekt
md src\test\java\integrationtest
rd src\main\resources
tree /F
Sie erhalten:
[\MeinWorkspace\SeleniumJetty] |- [src] | |- [main] | | |- [java] | | | '- [de] | | | '- [meinefirma] | | | '- [meinprojekt] | | '- [webapp] | | |- [WEB-INF] | | | '- web.xml | | '- index.jsp | '- [test] | '- [java] | |- [de] | | '- [meinefirma] | | '- [meinprojekt] | '- [integrationtest] '- pom.xml
Ersetzen Sie im Projektverzeichnis den Inhalt der pom.xml durch:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>SeleniumJetty</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>SeleniumJetty: Webapp mit Selenium-Integrationstest</name> <properties> <browser>firefox</browser> <selenium.port>4455</selenium.port> <servlet.port>8080</servlet.port> <appsrv.url>http://localhost:${servlet.port}</appsrv.url> <contextpath>${project.artifactId}</contextpath> </properties> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.26</version> <configuration> <scanIntervalSeconds>10</scanIntervalSeconds> <stopPort>9999</stopPort> <stopKey>geheim</stopKey> </configuration> <executions> <execution> <id>start-jetty</id> <phase>pre-integration-test</phase> <goals> <goal>run</goal> </goals> <configuration> <scanIntervalSeconds>0</scanIntervalSeconds> <daemon>true</daemon> </configuration> </execution> <execution> <id>stop-jetty</id> <phase>post-integration-test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>selenium-maven-plugin</artifactId> <version>2.3</version> <executions> <execution> <id>start-selenium</id> <phase>pre-integration-test</phase> <goals> <goal>start-server</goal> </goals> <configuration> <background>true</background> <logOutput>true</logOutput> <multiWindow>true</multiWindow> </configuration> </execution> <execution> <id>stop-selenium</id> <phase>post-integration-test</phase> <goals> <goal>stop-server</goal> </goals> </execution> </executions> <configuration> <port>${selenium.port}</port> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.12</version> <configuration> <systemPropertyVariables> <browser>${browser}</browser> <seleniumPort>${selenium.port}</seleniumPort> <appsrvUrl>${appsrv.url}</appsrvUrl> <contextPath>${contextpath}</contextPath> </systemPropertyVariables> <excludes> <exclude>**/integrationtest/*Test.java</exclude> </excludes> </configuration> <executions> <execution> <id>integration-tests</id> <phase>integration-test</phase> <goals> <goal>test</goal> </goals> <configuration> <skip>false</skip> <excludes> <exclude>none</exclude> </excludes> <includes> <include>**/integrationtest/*Test.java</include> </includes> </configuration> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>2.24.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-server</artifactId> <version>2.24.1</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> </dependencies> </project>
Erläuterungen zu den Konfigurationsoptionen des Jetty-Plugins finden Sie unter http://jetty.mortbay.org/jetty/maven-plugin/run-mojo.html (sehen Sie sich insbesondere scanIntervalSeconds und daemon an).
Erläuterungen zu den Optionen des Surefire-Test-Plugins finden Sie unter http://maven.apache.org/plugins/maven-surefire-plugin/ und maven-surefire-plugin/howto.html.
Ersetzen Sie im src\main\webapp-Verzeichnis den Inhalt der index.jsp durch:
<html> <head><title>Startseite</title></head> <body> <h2>Startseite</h2> <p><a name="BerechnungsFormular" href="BerechnungsFormular.jsp">Berechnungsformular</a></p> </body> </html>
Fügen Sie im src\main\webapp-Verzeichnis folgende BerechnungsFormular.jsp hinzu:
<%@ page import="de.meinefirma.meinprojekt.MeineBean" %> <html> <head><title>Webseite mit Berechnungsformular</title></head> <body> <h2>Webseite mit Berechnungsformular</h2> <% String wert1 = request.getParameter( "wert1" ); String wert2 = request.getParameter( "wert2" ); if( wert1 == null ) wert1 = ""; if( wert2 == null ) wert2 = ""; String ergebnis = (new MeineBean()).berechne( wert1, wert2 ); %> <form name="meinFormular" method="post"><pre> Wert1 <input type="text" name="wert1" value='<%= wert1 %>' size=10 maxlength=10><br> Wert2 <input type="text" name="wert2" value='<%= wert2 %>' size=10 maxlength=10><br> <input type="submit" name="berechne" value="berechne"> <input type="text" name="ergebnis" value='<%= ergebnis %>' size=10 readonly><br> </pre></form> </body> </html>
Erstellen Sie im src\main\java\de\meinefirma\meinprojekt-Verzeichnis eine JavaBean: MeineBean.java
package de.meinefirma.meinprojekt; public class MeineBean { public String berechne( String d1, String d2 ) { try { return "" + (Double.parseDouble( d1 ) + Double.parseDouble( d2 )); } catch( Exception ex ) { return ""; } } }
Erstellen Sie im src\test\java\de\meinefirma\meinprojekt-Verzeichnis einen Komponenten-JUnit-Test: MeineBeanTest.java
package de.meinefirma.meinprojekt; import org.junit.*; public class MeineBeanTest { @Test public void testMeineBean() { MeineBean meineBean = new MeineBean(); Assert.assertEquals( "3.0", meineBean.berechne( "1", "2" ) ); } }
Erstellen Sie im src\test\java\integrationtest-Verzeichnis einen Selenium-Integrationstest: SeleniumIntegrTest.java
package integrationtest; import org.junit.*; import com.thoughtworks.selenium.*; public class SeleniumIntegrTest { private Selenium selenium; private String contextPath; @Before public void startSelenium() { int seleniumPort = Integer.parseInt( System.getProperty( "seleniumPort" ) ); String browser = System.getProperty( "browser" ); String appsrvUrl = System.getProperty( "appsrvUrl" ); contextPath = System.getProperty( "contextPath" ); selenium = new DefaultSelenium( "localhost", seleniumPort, "*" + browser, appsrvUrl ); selenium.start(); selenium.setSpeed( "500" ); } @After public void stopSelenium() { selenium.stop(); } @Test public void test() { selenium.open( contextPath ); selenium.waitForPageToLoad( "33000" ); Assert.assertTrue( selenium.isTextPresent( "Startseite" ) ); selenium.click( "link=Berechnungsformular" ); selenium.waitForPageToLoad( "33000" ); Assert.assertTrue( selenium.isTextPresent( "Webseite mit Berechnungsformular" ) ); selenium.type( "wert1", "49.7" ); selenium.type( "wert2", "-7.7" ); selenium.click( "berechne" ); selenium.waitForPageToLoad( "33000" ); Assert.assertEquals( "42.0", selenium.getValue( "name=ergebnis" ) ); } }
Die Projektstruktur sieht jetzt so aus (überprüfen Sie es mit tree /F):
[\MeinWorkspace\SeleniumJetty] |- [src] | |- [main] | | |- [java] | | | '- [de] | | | '- [meinefirma] | | | '- [meinprojekt] | | | '- MeineBean.java | | '- [webapp] | | |- [WEB-INF] | | | '- web.xml | | |- BerechnungsFormular.jsp | | '- index.jsp | '- [test] | '- [java] | |- [de] | | '- [meinefirma] | | '- [meinprojekt] | | '- MeineBeanTest.java | '- [integrationtest] | '- SeleniumIntegrTest.java '- pom.xml
Manueller Test im Webbrowser:
cd \MeinWorkspace\SeleniumJetty
mvn jetty:run
Warten Sie bis "Started Jetty Server" erscheint und rufen Sie dann im Webbrowser auf:
http://localhost:8080/SeleniumJetty
Klicken Sie auf den Berechnungsformular-Link, tragen Sie auf der folgenden Webseite zwei Zahlen ein und betätigen Sie "berechne": Sie erhalten die Summe.
Beenden Sie Jetty mit "Strg + C".
Manueller Aufruf des JUnit-Komponententests:
cd \MeinWorkspace\SeleniumJetty
mvn test -Dtest=de.meinefirma.meinprojekt.MeineBeanTest
Manueller Aufruf des Selenium-Integrationstests:
Starten Sie Jetty mit der Webanwendung, den Selenium-Server und den Integrationstest (es werden zwei zusätzliche Kommandozeilenfenster geöffnet):
cd \MeinWorkspace\SeleniumJetty
start cmd /C mvn jetty:run
start cmd /C mvn selenium:start-server
mvn test -Dtest=integrationtest.SeleniumIntegrTest
Beenden Sie den Jetty-Server und den Selenium-Server jeweils mit "Strg + C".
Automatisierter Integrationstest:
Der wichtigste Trick in diesem Beispiel ist die vollständig automatisierte Ausführung der Integrationstests inklusive automatischem Start des Jetty-Servers in einem zusätzlichen Hintergrund-Thread (über <daemon>true</daemon>), Ausführung der Integrationstests und anschließend der automatischen Beendigung von Jetty mit folgendem Kommando:
mvn clean verify
Oder, falls Sie mit einem anderen Webbrowser als Mozilla Firefox testen wollen, zum Beispiel mit Microsoft Internet Explorer:
mvn clean verify -Dbrowser=iexploreproxy
Sie erhalten zwei Testphasen, zuerst default-test und dann integration-tests:
... [INFO] --- maven-surefire-plugin:2.12:test (default-test) @ SeleniumJetty --- ... ------------------------------------------------------- T E S T S ------------------------------------------------------- ... Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ... ... [INFO] Starting jetty 6.1.26 ... ... [INFO] Started Jetty Server ... Launching Selenium Server ... Selenium Server started ... [INFO] --- maven-surefire-plugin:2.12:test (integration-tests) @ SeleniumJetty --- ... ------------------------------------------------------- T E S T S ------------------------------------------------------- ... Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
Das folgende Beispiel verwendet statt des nur für Jetty geeigneten Jetty-Maven-Plugins das universellere Cargo-Maven-Plugin. Doku hierzu finden Sie unter https://codehaus-cargo.github.io/cargo/Maven2+plugin und https://codehaus-cargo.github.io/cargo/Maven2+Plugin+Reference+Guide.
Dieses Beispiel verwendet wieder Jetty. Das sich anschließende Beispiel ist für andere Application Server geeignet.
Dieses Beispiel setzt die Durchführung des letzten Beispiels ("SeleniumJetty") voraus.
Erzeugen Sie eine Kopie des letzten Beispiels ("SeleniumJetty"):
cd \MeinWorkspace
xcopy SeleniumJetty SeleniumCargo\ /S
cd SeleniumCargo
Ersetzen Sie im neuen SeleniumCargo-Verzeichnis in der pom.xml an zwei Stellen SeleniumJetty durch SeleniumCargo.
Entfernen Sie im neuen SeleniumCargo-Verzeichnis in der pom.xml den
"<plugin>...maven-jetty-plugin...</plugin>"-Block.
Ersetzen Sie ihn durch:
<plugin> <groupId>org.codehaus.cargo</groupId> <artifactId>cargo-maven2-plugin</artifactId> <version>1.2.2</version> <configuration> <wait>false</wait> <container> <containerId>jetty6x</containerId> <type>embedded</type> </container> </configuration> <executions> <execution> <id>start-container</id> <phase>pre-integration-test</phase> <goals> <goal>start</goal> <goal>deploy</goal> </goals> </execution> <execution> <id>stop-container</id> <phase>post-integration-test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions> </plugin>
Führen Sie den Selenium-Integrationstest aus:
cd \MeinWorkspace\SeleniumCargo
mvn clean verify
Oder mit Internet Explorer statt Firefox:
mvn clean verify -Dbrowser=iexploreproxy
Sie erhalten wieder zwei Testphasen, zuerst default-test und dann integration-tests:
... [INFO] --- maven-surefire-plugin:2.12:test (default-test) @ SeleniumCargo --- ... ------------------------------------------------------- T E S T S ------------------------------------------------------- ... Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ... ... [INFO] [beddedLocalContainer] Jetty 6.x Embedded starting... ... [INFO] [beddedLocalContainer] Jetty 6.x Embedded started on port [8080] ... Launching Selenium Server ... Selenium Server started ... [INFO] --- maven-surefire-plugin:2.12:test (integration-tests) @ SeleniumCargo --- ... ------------------------------------------------------- T E S T S ------------------------------------------------------- ... Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 ... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
Sehen Sie sich auch das Cargo-Beispiel unter Automatisierter Integrationstest mit Cargo für WebLogic, JBoss und Tomcat an.
Dieses Beispiel bietet folgende Erweiterungen:
Führen Sie folgende Schritte durch:
Dieses Beispiel setzt die Durchführung des vorletzten Beispiels ("SeleniumJetty") voraus.
Erzeugen Sie eine Kopie des vorletzten Beispiels ("SeleniumJetty"):
cd \MeinWorkspace
xcopy SeleniumJetty SeleniumCargoZipped\ /S
cd SeleniumCargoZipped
Ersetzen Sie im neuen SeleniumCargoZipped-Verzeichnis in der pom.xml an zwei Stellen SeleniumJetty durch SeleniumCargoZipped.
Achten Sie darauf, dass in der pom.xml in der Zeile "<selenium.port>4455</selenium.port>" als Selenium-Port nicht 4444 eingesetzt ist, sondern zum Beispiel 4455 (4444 benötigt JBoss).
Entfernen Sie im neuen SeleniumCargoZipped-Verzeichnis in der pom.xml den
"<plugin>...maven-jetty-plugin...</plugin>"-Block.
Ersetzen Sie ihn durch:
<plugin> <groupId>org.codehaus.cargo</groupId> <artifactId>cargo-maven2-plugin</artifactId> <version>1.2.2</version> <configuration> <wait>false</wait> <container> <containerId>${cargo.containerId}</containerId> <zipUrlInstaller> <url>${zipUrlInstaller.url}</url> <downloadDir>${project.build.directory}/appsrvInstallDir</downloadDir> <extractDir>${project.build.directory}/appsrvInstallDir</extractDir> </zipUrlInstaller> <output>${project.build.directory}/${cargo.containerId}.log</output> <log>${project.build.directory}/cargo.log</log> </container> <configuration> <home>${project.build.directory}/${cargo.containerId}/container</home> <properties> <cargo.logging>high</cargo.logging> <cargo.servlet.port>${servlet.port}</cargo.servlet.port> </properties> </configuration> </configuration> <executions> <execution> <id>start-container</id> <phase>pre-integration-test</phase> <goals> <goal>start</goal> <goal>deploy</goal> </goals> </execution> <execution> <id>stop-container</id> <phase>post-integration-test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions> </plugin>
Fügen Sie in der pom.xml am Ende vor </project> hinzu:
<profiles> <profile> <id>tomcat7x</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <cargo.containerId>tomcat7x</cargo.containerId> <zipUrlInstaller.url>http://www.apache.org/dist/tomcat/tomcat-7/v7.0.21/bin/apache-tomcat-7.0.21.zip</zipUrlInstaller.url> </properties> </profile> <profile> <id>jboss7x</id> <properties> <cargo.containerId>jboss7x</cargo.containerId> <zipUrlInstaller.url>http://download.jboss.org/jbossas/7.0/jboss-as-7.0.0.Final/jboss-as-7.0.0.Final.zip</zipUrlInstaller.url> </properties> </profile> </profiles>
Führen Sie den Selenium-Integrationstest für Tomcat aus (bitte beachten: der erste Aufruf kann wegen des Downloads etwas dauern):
cd \MeinWorkspace\SeleniumCargoZipped
mvn verify
Oder mit Internet Explorer statt Firefox:
mvn verify -Dbrowser=iexploreproxy
Sie erhalten wieder die beiden Testphasen default-test und integration-tests sowie als Ergebnis BUILD SUCCESS.
Führen Sie den Selenium-Integrationstest für JBoss aus (bitte beachten: der erste Aufruf kann wegen des großen Downloads etwas länger dauern):
cd \MeinWorkspace\SeleniumCargoZipped
mvn verify -Pjboss7x
Oder mit Internet Explorer statt Firefox:
mvn verify -Pjboss7x -Dbrowser=iexploreproxy
Sie erhalten wieder die beiden Testphasen default-test und integration-tests sowie als Ergebnis BUILD SUCCESS.
In der pom.xml können Sie in den beiden <profile>-Sektionen bei <zipUrlInstaller.url> statt der beiden Internet-URLs
<zipUrlInstaller.url>http://...</zipUrlInstaller.url>
auch Pfade in Ihrem Dateisystem angeben, für Tomcat zum Beispiel so:
<zipUrlInstaller.url>file:///C:\_Pfad-zur-Tomcat-Zipdatei_\apache-tomcat-6.0.32.zip</zipUrlInstaller.url>
So können Sie am einfachsten vermeiden, dass nach einem mvn clean ein erneuter Download übers Internet erforderlich wird. Alternativ könnten Sie auch in der cargo-<plugin>-Sektion bei
<zipUrlInstaller> ... <downloadDir>${project.build.directory}/appsrvInstallDir</downloadDir> <extractDir>${project.build.directory}/appsrvInstallDir</extractDir> </zipUrlInstaller>
ein Verzeichnis außerhalb des target-Verzeichnisses angeben (z.B.: ${basedir}/target-appsrvInstallDir).
Falls Sie die Fehlermeldung "Failed to download ... Caused by: java.net.ConnectException: Connection timed out: connect" erhalten (z.B. weil Sie sich in einem Proxy-geschützten Firmennetz befinden), dann sollten Sie die Zipdateien separat downloaden, im Dateisystem speichern und bei <zipUrlInstaller.url> statt der Internet-URLs Dateipfade eintragen (<zipUrlInstaller.url>file://...</zipUrlInstaller.url>).
Wie Sie nicht nur einige Properties mit Profilen umschalten können (wie in diesem Beispiel), sondern viele weitere Cargo-Plugin-Eigenschaften, zeigt das Beispiel unter https://codehaus-cargo.github.io/cargo/Maven2+Plugin+Tips#Maven2PluginTips-tip1.
Sehen Sie sich auch das Cargo-Beispiel unter Automatisierter Integrationstest mit Cargo für WebLogic, JBoss und Tomcat an.