PHP Webdriver Tests mit Jenkins

Ich hatte in der Vergangenheit bereits etwas über den Einsatz von Selenium zum Automatisierten Testen von Webanwendungen im Artikel Automatisierte Browsertests mit Selenium und PHP Webdriver geschrieben. Man sollte auch diesen Artikel zunächst gelesen haben, um die weiteren Informationen in diesem Artikel besser verstehen zu können.

Heute möchte ich eines meiner automatisierten PHP Testskripten erläutern, welches die Funktion einer Website von verschiedenen Plattformen (Window7, WindowsXP und Suse Linux Enterprise Server) automatisch testet. Im Grunde wird natürlich die Funktionsweise einer Website in verschiedenen Browser (Internet Explorer, Firefox und Chrome) auf den genannten Plattformen überprüft.

Damit man das folgende PHP Script einsetzen kann, muss man verstehen dass es für eine bestimmte Systemumgebung konzipiert ist. Das PHP Skript ist ein Test-Plan mit einzelnen Testfällen. Jeder einzelne von den Testfällen wird auf den drei vorgenannten Testservern ausgeführt und testet die einzelnen Testfällen in den installierten Browsern. Bevor man beginnen kann, muss man zunächst mindestens einen Test Plattform mit Selenium aufbauen, hierfür findet man die Anleitung in dem Artikel Webdriver Testsystem für Selenium installieren und einrichten. Ohne das hat das Weiterlesen an dieser Stelle keinen Sinn 😉

Im ersten Schritt sollte man das PHP Script auf die eigene Testumgebung konfigurieren. Hierfür stellt man im Bereich settings and preparations erstmal die verfügbaren Browsern auf den Testsystemen ein. Hierfür existiert für jedes Testsystem ein Array in dem die Namen der zu testenden Browser definiert werden. Die Arrays Win7, WinXP und SLES werden daher einfach mit den verfügbaren Browsern bestückt. D.h. wenn man auf dem Testsystem für Windows 7 (Win7) nur einen Internet Explorer testen möchte, muss man dem entsprechend alle anderen Browser aus dem Array entfernen.

Wenn man nun die Browser auf den Testssystemen definiert hat, muss man natürlich noch die URL zu dem Testserver bekannt geben. Dieses URL zielt auf den Installierten Selenium Webdriver und wird in der Varibale $host gespeichert. Z.B. für den Window 7 Testserver habe ich definiert: $host = ‚http://win7-selenium-server:4444/wd/hub‘

Denkt daran, man muss vorher den Selenium Webdriver auf dem Testsystem installiert und gestartet haben.

Damit man mit dem automatisierten Testen endlich loslegen kann, muss man erstmal einen Testcase definieren und programmieren. Hierfür nutze ich gerne den Selenium Builder, um den Testcase aufzunehmen und dann den PHP Code direkt zu exportieren. Ihr findet eine kurze Zusammenfassung im Artikel Firefox Plugin Selenium Builder. Der Selenium Builder ist ein wirklich komfortables Tool um direkt den Testfall so zu strukturieren, wie er im Bereich Testcase in diesem PHP Script benutzt wird.

In dem folgenden PHP Script wird ein einfacher Testfäll ausgeführt. Der Testfall ruft ein Kontaktformular auf und füllt alle Felder mit sinnvollen Werten aus. Danach wird das Formular abgeschickt und die Erfolgsmeldung abgefragt. Wenn das funktioniert, gilt der Testfall als erfolgreich und das PHP Script endet mit dem Returncode 0. Wenn ein Fehler bei diesem Test auftritt wird der Returncode 1 gesetzt und ein Screenshot des Browsers gemacht. Somit hat man neben dem Fehlertext auch ein Visuelles Mittel um den Fehler bessern nachvollziehen zu können.

<?php
/*
@copyright          2014
@author             Andreas Baßermann
@email              ab@agile-coding.net
@created            24.04.2014
@file-summary       This file is a Template for automatic browser testing with selenium php-webdriver
                    You got to loop a testcase within the try´n catch
                    When you going to check a test and recognize errors, throw an exception, the script is doing 
                    a screenshot and sets the returncode
*/
 
/*
##########################################################################
 
    testplan [Namen], [Version]
 
##########################################################################
*/
 
/*
##########################################################################
 
    settings and preparations
 
##########################################################################
*/
 
/* including the Webdriver framework */
require "PHPWebDriver/__init__.php";
 
/* setting invinite timelimit for the script, test can run a long time  */
set_time_limit(0);
 
/* setting some vars of the script */
$tpname = 'Browser compatibily Firefox'; //name of the testplan
$tpversion = '1.0'; //version of the testplan
$selenium ='http://test-host/site'; //path of the server where the testscript runs 
 
/* define which OS and Browser should be tested, it obvious, Internet Explorer is not possible on Linux (SLES) */
$Win7 = array(    "internet explorer",
                "chrome",
                "safari",
                "firefox");
 
$WinXP = array(    "internet explorer",
                "chrome",
                "firefox");
 
$SLES = array(    "firefox");
 
/*
##########################################################################
 
    preparing the test on diffrent environment
 
##########################################################################
*/
/* looping the browser on windows7 testsystem */
foreach ($Win7 as $system){
 
    /* setting the selenium server */
    $host = 'http://win7-selenium-server:4444/wd/hub';    
    
    switch ($system) {
        case "internet explorer":
            $browser = "internet explorer";
            break;
        case "chrome":
            $browser = "chrome";
            break;
        case "safari":
            $browser = "safari";
            break;
        case "firefox":
            $browser = "firefox";
            break;
    }
 
    /* fire the testcases */
    do_tests($selenium, $host, $browser, $tpname, $tpversion);    
}                    
 
/* looping the browser on WindowsXP testsystem */
foreach ($WinXP as $system){
 
    /* setting the selenium server */
    $host = 'http://win-xp-selenium-server:4444/wd/hub';    
 
    switch ($system) {
        case "internet explorer":
            $browser = "internet explorer";
            break;
        case "chrome":
            $browser = "chrome";
            break;
        case "safari":
            $browser = "safari";
            break;
        case "firefox":
            $browser = "firefox";
            break;
    }
    
    /* fire the testcases */
    do_tests($selenium, $host, $browser, $tpname, $tpversion);    
}    
 
/* looping the browser on Linux (SLES) testsystem */
foreach ($SLES as $system){
 
    /* setting the selenium server */
    $host = 'http://linux-selenium-server:4444/wd/hub';
 
    switch ($system) {
        case "internet explorer":
            $browser = "internet explorer";
            break;
        case "chrome":
            $browser = "chrome";
            break;
        case "safari":
            $browser = "safari";
            break;
        case "firefox":
            $browser = "firefox";
            break;
    }
    /* fire the testcases */
    do_tests($selenium, $host, $browser, $tpname, $tpversion);    
}    
    
/*
##########################################################################
 
    setting success returncode
 
##########################################################################
*/
exit(0);
 
/*
##########################################################################
 
    The Tests 
 
##########################################################################
*/
function do_tests($selenium, $host, $browser, $tpname, $tpversion){
/*
    Starting the single tests
*/
    try {
    
        /* creating the session to the selenium server */            
        $driver = new PHPWebDriver_WebDriver($host);        
 
        /* defining the session for the webdriver */
        $session = $driver->session($browser);
 
        /* always maximizing the remotebrowser*/
        $session->window()->maximize();
    
        /*
        ##########################################################################
 
            testcase # 1 
            
            [copy the entire testcase for creating another one]
 
        ##########################################################################
        */
 
        /* while creating you can skipt singel testcases, do not forget setting fals for production */
        $skiptit = TRUE;
        
        if ($skiptit == FALSE){
            /* setting the vars for the testcase */
            $tcname = 'Browser compatibily '; //name of the testcase
            $tcnumber = '1'; //number of the testcase
            
            /* open the page */
            $session->open('http://172.16.70.12/er-bau/kontakt/kontaktformular/');
 
            //checking the page titel, if not Kontaktformular, then stop the entire test
            if (! (strpos($session->element("tag name", "html")->text(), "Kontaktformular") !== false)) {
                throw new Exception('headline Kontaktformular wasn found');
            };    
 
            /* fill the contact form with some datas */        
            $result = $session->element('id', 'firstname');
            $result->sendKeys('Peter');
            
            $result = $session->element('id', 'surename');
            $result->sendKeys('Lustig');
            
            $result = $session->element('id', 'tel');
            $result->sendKeys('12345678');
            
            $result = $session->element('id', 'email');
            $result->sendKeys('test@netzwerk-design.de');
            
            $result = $session->element('id', 'address');
            $result->sendKeys('Ludwigstrasse');
            
            $result = $session->element('id', 'str-number');
            $result->sendKeys('8');
            
            $result = $session->element('id', 'plz');
            $result->sendKeys('63217');
            
            $result = $session->element('id', 'city');
            $result->sendKeys('Offenbach');
            
            $result = $session->element('id', 'subject');
            $result->sendKeys('Test Mail Kontaktformular Windows 7 - Firefox');
            
            $result = $session->element('id', 'message');
            $result->sendKeys('Dies ist ein Test des Kontaktformular.');
            
            // submit the form
            $result = $session->element('id', 'submit')->submit('');
            
            //need a break to wait for reload of the page
            sleep(10);        
            
            // check if the respondse message is correct
            if ($session->element("class name", 'wpcf7-response-output')->displayed('') == 0) {
                throw new Exception('succsess respond message "wpcf7-response-output" wasn´t shown');
            };
        }
        /*
        ##########################################################################
 
            testcase # 2 
 
        ##########################################################################
        */
        
    }
    catch (Exception $e){
        
        /* dumping the error message */
        echo $e.PHP_EOL;
        
        /* dumping the environment  */
        var_dump($session->capabilities());
        
        /* finally take a screenshot and save it with filename reference to this testcase */
        echo 'screenhot: '.get_screenshot($session, $tpname, $tpversion, $tcname, $tcnumber, $selenium);
        
        /* cleaning up and closing session */
        $session->close();
        exit(1);
    }
    /* closing the session to the selenium server */
    $session->close();
}
/*
##########################################################################
 
    functions 
 
##########################################################################
*/
function get_screenshot($session, $tpname, $tpversion, $tcname, $tcnumber, $selenium){
    /* setting the vars for a screenshot */
    $img = $session->screenshot();
    $data = base64_decode($img);
    $file = $tpname.'_'.$tpversion.'_'.$tcname.'_'.$tcnumber.'.png';
 
    /* finally take a screenshot and save it with filename referenz to this testcase */
    try{
        $sc = file_put_contents($file, $data);
        $scfile = $selenium."/".$file.PHP_EOL;  
    }
    catch (Exception $e){
        echo 'it was not possible to generate a screenshot'.PHP_EOL;
        echo $e.PHP_EOL;
        exit(1);
    }
    return $scfile;
}
?>

Ich benutze das Skript im Zusammenhang mit Jenkins. Genauer gesagt, der Jenkins wird benutzt um die entwickelte Website auf einem Webserver zu installieren und im Nachgang wird dieses PHP Script ausgeführt, um die definierten Testfälle ab zu prüfen. Wenn die Auslieferung und die Testfälle erfolgreich waren, endet der Jenkins Job erfolgreich und ich kann mir sicher sein, dass die Qualität der Website weiterhin gegeben ist.

http://www.agile-coding.net/php-webdriver-tests-mit-jenkins/