Selenium ganz in der Cloud

Meine bisherigen Blogbeiträge haben nur die Testausführung in die Cloud (saucelabs.com) geschickt (also sozusagen den „Tanz“ mit den Browsern“). Der Seleniumcode residierte dabei auf meinem lokalen Rechner und wurde dort auch ausgeführt. Wie wäre es nun, wenn ich als Selenium-Dienstleister meinem Kunden einfach nur ein „Testbutton im Internet“ bereitstellen müsste, damit er seine Tests zum Fliegen bringt und dort dann anschließend auch das Testergebnis zu sehen bekommt. All dies kann man beispielsweise mit cloudbees.com umsetzen, wo Kohsuke Kawaguchi, der Papa von Jenkins (und Hudson) inzwischen angestellt ist. Dort bekommt man beispielsweise eine vorkonfigurierte Jenkins-Instanz, eine Maveninstallation, diverse Repositories usw. – alles als Platform as a Service in der Cloud.
In diesem Blogpost verwendete Tools: Cloudbees DEV@cloud (svn-repository, Jenkins, Sauce Labs OnDemand), Maven, TestNG, Subversion, TortoiseSVN
In diesem Blogpost verwendeter Code:
Maven – pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>de.itkosmopolit.blog</groupId>
    <artifactId>paralleltest</artifactId>
    <version>1.0-SNAPSHOT</version>
	 <properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	 </properties>
    <dependencies>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>5.13.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium</artifactId>
            <version>2.0b1</version>
        </dependency>
	</dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
				<version>2.12.3</version>
                <configuration>
					<parallel>methods</parallel>
					<threadCount>2</threadCount>
                </configuration>
            </plugin>
		</plugins>
    </build>
</project>

ParallelTest.java (Selenium-Code)

package de.itkosmopolit.blog;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.Test;
import org.testng.Assert;
import java.net.URL;
import java.net.MalformedURLException;
public class ParallelTest {
    @Test
    public void parallel_with_firefox() throws MalformedURLException{
		//Konfigurationen
		DesiredCapabilities caps = DesiredCapabilities.firefox(); //Browser auswählen
        caps.setCapability("version", "13"); //Version des Browsers festlegen
        caps.setCapability("platform", "Linux"); //Betriebssystem festlegen
		caps.setCapability("name", "parallelTestFirefox"); //hier wird der Test benannt und in SauceLabs wieder auffindbar.
		caps.setCapability("username", "cloudbees_it-kosmopo"); //Mein Username bei SauceLabs
		caps.setCapability("accessKey", "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"); //Mein Access-key bei SauceLabs
        RemoteWebDriver driver = new RemoteWebDriver(
                new URL("https://cloudbees_it-kosmopo:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx@ondemand.saucelabs.com:80/wd/hub"),
                caps);
		//Testcase
        driver.get("https://www.it-kosmopolit.de");
        driver.findElementByLinkText("KONTAKT UND ANGEBOT").click();
		WebElement profil = driver.findElement(By.partialLinkText("xing"));
		Assert.assertTrue(profil.getText().contains("Michael_Wowro"));
		//Beenden
        driver.quit();
    }
	 @Test
    public void parallel_with_internetExplorer() throws MalformedURLException {
	    //Konfigurationen
		DesiredCapabilities caps = DesiredCapabilities.internetExplorer(); //Browser auswählen
        caps.setCapability("version", "9"); //Version des Browsers festlegen
        caps.setCapability("platform", "Windows 2008"); //Betriebssystem festlegen
		caps.setCapability("name", "parallelTestInternetExplorer"); //hier wird der Test benannt und in SauceLabs wieder auffindbar.
		caps.setCapability("username", "cloudbees_it-kosmopo"); //Mein Username bei SauceLabs
		caps.setCapability("accessKey", "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"); //Mein Access-key bei SauceLabs
        RemoteWebDriver driver = new RemoteWebDriver(
                new URL("https://cloudbees_it-kosmopo:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx@ondemand.saucelabs.com:80/wd/hub"),
                caps);
		//Testcase
        driver.get("https://www.it-kosmopolit.de");
        driver.findElementByLinkText("KONTAKT UND ANGEBOT").click();
		WebElement profil = driver.findElement(By.partialLinkText("xing"));
		Assert.assertTrue(profil.getText().contains("Michael_Wowro"));
		//Beenden
        driver.quit();
    }
}

Hier ist ein Quickstart, den ich als Ausgangspunkt für meinen Post genutzt habe: http://wiki.cloudbees.com/bin/view/DEV/Sauce+OnDemand+Service. Und noch ein Quickstart-Video: http://www.youtube.com/watch?v=NENNAZQxK28&feature=youtu.be
1.) Also brauchen wir ein Konto bei cloudbees, welches einfach anzulegen und in der Variante für unter 300 Minuten/Monat kostenlos ist: https://www.cloudbees.com/signup

Das was wir dort unter Domain/Account eingeben ist Teil der URL, mit der wir nach erfolgreicher Anmeldung unsere Jenkins-Instanz direkt erreichen können: https://[accountname].ci.cloudbees.com
Alternativ erreichen wir diese in unserem cloudbees-Konto mit Click auf den Builds-Button in der Navigationsleiste

2.) Im nächsten Schritt abonnieren wir den Service: Sauce Labs (s.u. Abbildung) – Achtung, hierbei wird automatisch ein neues (!) Sauce Labs Konto erstellt mit eigenen Credentials.

3.) Nun legen wir ein Subversion-Repository in cloudbees an – (Repositories-Button in der Navigationsleiste)
Von cloudbees aus betrachtet sieht das Ergebnis dann so aus:

4.) In diesem Repository hab ich per TortoiseSVN die pom.xml (/pom.xml) und die ParallelTest.java (/src/test/java/ParallelTest.java) importiert und zwar, wie in den Klammern gezeigt, in der Standard-Maven Verzeichnisstruktur.
5.) Als letzter Schritt bleibt noch, den Jenkins-Job anzulegen
5.1) Wir tragen den Projektnamen ein und wählen Maven 2 / 3 Projekt aus.
5.2) In der Rubrik „Source Code Management“ wählen wir Subversion und tragen die URL unseres cloudbee-repositories ein.

5.3) Als Build-Auslöser habe ich „Build when a change is pushed to CloudBees Forge“ angehakt. Dadurch startet der Build automatisch, sobald ich ins cloudbees Subversion-Repository committe. Das funktioniert bei cloudbees zuverlässig, wenn auch ein paar Sekunden zeitverzögert, da erst ein Build-Prozess frei werden muss. Selbst wenn ich die Seleniumtests lokal entwickle und auch lokal überprüfe, ob diese fehlerfrei durchlaufen, so kann ich mit dieser Konfiguration doch nachvollziehbar dokumentieren, dass meine Tests zum Zeitpunkt des commits fehlerfrei durchgelaufen sind.
5.4) In der Rubrik „build“ verweise ich auf die pom.xml (wie bereits voreingestellt) und trage als Maven-Phase test ein.

[Exkurs: Falls die Entwickler meines Kunden Maven als Buildtool nutzen, kann ich Ihnen meine Tests auch als jar in cloudbees Maven-reposity zur Verfügung stellen: http://maven.apache.org/guides/mini/guide-attached-tests.html. Aber Ziel dieses Blogposts ist ja, meinem Kunden einen „Testbutton im Internet“ zur Verfügung zu stellen. Also weiter …]
5.5) Den Rest lassen wir bei den default-Einstellungen. Die Einstellungen können natürlich über „Konfigurieren“ jederzeit geändert werden.
FERTIG – etwas Aufwand, aber nun können wir unserem Kunden einen „Test-Button im Internet“ geben, mit dem er seine Tests rennen lassen kann. Was er braucht, ist (abgesehen von Account-Credentials) nur die URL des Jenkins-Jobs (https://[accountname].ci.cloudbees.com/job/[jobname]).
Im Build-Verlauf erkennt er, ob die letzten „Builds“ (bei unserer Verwendung von Jenkins vielleicht besser als „Testläufe“ zu bezeichnen) erfolgreich waren oder nicht.

blau = Testlauf war fehlerfrei
gelb = Testlauf war fehlerbehaftet
Mit diesem Button startet er seine Seleniumtests:

Wenn’s geknallt hat, kann er auf den entsprechenden Build clicken und schauen, wo es genau geknallt hat:

Das dazugehörige Log kann mein Kunde natürlich auch einsehen und die entsprechenden SauceLabs-Videos (unter Services -> Sauce Labs).
Und wieder habe ich diese Videos für die Öffentlichkeit freigegeben, welche aufgrund der Einfachheit der Testcases nicht spektakulär daherkommen:
parallelTestInternetExplorer
parallelTestFirefox

2 Gedanken zu „Selenium ganz in der Cloud“

  1. Nice job, Michael! I enjoyed reading your blog. Und in Deutsch, ich spreche das ist sehr gut! Keep up the good work and thanks for sharing this information with the developer community. Selenium + CloudBees = smooth development/testing.

Kommentare sind geschlossen.