Digitalagentur für Business Software aus Kiel

Schnelleinstieg - Tests mit Codeception, Selenium und Chrome

Veröffentlicht von Sebastian Schmidt am 11.09.2014

Sebastian Schmidt

Das Testframework Codeception erlaubt die unkomplizierte Ausführung von Unit-Tests, Functional-Tests und Acceptance-Tests für PHP-Webprojekte.

Mit der interessanteste Anwendungsfall von Codeception ist sicherlich die Möglichkeit in Form von Acceptance-Tests mit wenigen Schritten ein Webprojekt aus der Sicht eines Benutzers zu testen. Die Tests selbst werden dabei im Gegensatz zu anderen Lösungen direkt in PHP verfasst. Um einen einfachen Test zu erstellen, muss zunächst Codeception in ein existierendes Webprojekt aufgenommen werden oder ein neues Projekt angelegt werden.

Zunächst erstellen wir in der Konsole einen neuen Ordner und installieren Composer.

cd /path/to/my/projects
mkdir quickstart-codeception
cd quickstart-codeception
curl -sS https://getcomposer.org/installer | php

Bei erfolgreicher Installation sollte folgende Ausgabe erscheinen:

All settings correct for using Composer
Downloading...

Composer successfully installed to: /Users/schmidt/henrikgit/blog-selenium/proj/quickstart-codeception/composer.phar
Use it: php composer.phar

Im nächsten Schritt wird Codeception über Composer installiert.

php composer.phar require "codeception/codeception:*"

Mit dem Befehl

php vendor/bin/codecept

können wir uns die Methoden ausgeben lassen, die das Framework anbietet. Bei erfolgreicher Installation erhält man die folgende Auflistung:

Codeception version 2.0.5

Usage:
  [options] command [arguments]

Options:
  --help           -h Display this help message.
  --quiet          -q Do not output any message.
  --verbose        -v|vv|vvv Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
  --version        -V Display this application version.
  --ansi              Force ANSI output.
  --no-ansi           Disable ANSI output.
  --no-interaction -n Do not ask any interactive question.

Available commands:
  bootstrap             Creates default test suites and generates all requires files
  build                 Generates base classes for all suites
  clean                 Cleans or creates _log directory
  console               Launches interactive test console
  help                  Displays help for a command
  list                  Lists commands
  run                   Runs the test suites
generate
  generate:cept         Generates empty Cept file in suite
  generate:cest         Generates empty Cest file in suite
  generate:group
  generate:helper       Generates new helper
  generate:pageobject   Generates empty PageObject class
  generate:phpunit      Generates empty PHPUnit test without Codeception additions
  generate:scenarios    Generates text representation for all scenarios
  generate:stepobject   Generates empty StepObject class
  generate:suite        Generates new test suite
  generate:test         Generates empty unit test file in suite

Um die Grundordnerstruktur und die notwendigen Dateien anzulegen führt man jetzt das Kommando

php vendor/bin/codecept bootstrap

aus.

Im Projektordner befinden sich nun unter anderem der Ordner tests/ und die Konfigurationsdatei codeception.yml. Betrachtet man den Inhalt des Ordners test/, so findet man hier die generierte Klasse AcceptanceTester.

Bei dieser Klasse handelt es sich innerhalb des Vokabulars des Frameworks um einen Akteur. Das Framework selbst betrachtet Tests immer als Aktionen, die durch eine Person ausgeführt werden. Akteure repräsentieren diese Personen und enthalten alle Aktionen die diese Personen durchführen können. Diese werden entsprechend der Konfiguration generiert. Für das aktuelle Ziel könnte dies die Aktion "die testende Person sieht unter der Url x den Inhalt y" sein. Die generierte Klasse AcceptanceTester enthält entsprechend eine Methode canSee().

Der Tester ist also definiert. Ein Test fehlt. Dies korrigieren wir durch Ausführung des Befehls

php ./vendor/bin/codecept generate:cest acceptance HomeOnline

, um jetzt in unserem Tests-Ordner im Unterverzeichnis acceptance/ die Datei HomeOnlineCest.php vorzufinden. Eine Cest-Klasse ist die als Klasse repräsentierte Form eines Tests innerhalb von Codeception. Alternativ kann man unter anderem die Cept-Variante wählen.

Der Inhalt unserer neuen Cest-Klasse ist im Folgenden dargestellt.

<?php

use \AcceptanceTester;

class HomeOnlineCest
{
    public function _before(AcceptanceTester $I)
    {
    }

    public function _after(AcceptanceTester $I)
    {
    }

    // tests
    public function tryToTest(AcceptanceTester $I)
    {
    }
}

Wir sehen hier, dass wir innerhalb einer Testklasse Vorbereitungs- und Aufräumarbeiten definieren können. Alle weiteren Methoden werden als Tests interpretiert. Dies bedeutet, dass aktuell die Methode tryToTest(AcceptanceTester $I) als einziger Test vorhanden ist.

 

Wir passen die Klasse wie folgt an, um die Erreichbarkeit unserer Startseite zu testen.

<?php
use \AcceptanceTester;

class HomeOnlineCest
{
    public function _before(AcceptanceTester $I)
    {
    }

    public function _after(AcceptanceTester $I)
    {
    }

    /**
     * Test is home available
     *
     * @param AcceptanceTester $I
     */
    public function backendLogin(AcceptanceTester $I)
    {
        $I->wantTo('check if our frontend-home is available');
        $I->amOnPage('/');
        $I->see('Als digitale Agentur mit den Schwerpunkten Design und Entwicklung von Webprojekten haben wir langjährige Erfahrung in der Betreuung von namhaften Kunden aus der Gaming- und Sportmarketing-Branche.');
    }
}

Es ist auch ohne Vorkenntnisse schnell deutlich, was unser Akteur im Rahmen des Tests tun soll. Er wird die Eingangsseite unserer Domain unter dem Pfad "/" aufrufen und dort im positiven Fall den Text "Als digitale Agentur mit den Schwerpunkten Design und Entwicklung von Webprojekten haben wir langjährige Erfahrung in der Betreuung von namhaften Kunden aus der Gaming- und Sportmarketing-Branche." vorfinden. Diese Form der Tests bringt den Vorteil, die Tests in lesbare Dokumente exportieren zu können.

Die aufzurufende Domain und weitere Konfiguration für die Acceptance-Tests findet in der Datei acceptance.suite.yml im bereits bekannten Tests-Ordner statt. Für einen ersten Probelauf sollte ihr Inhalt wie folgt aussehen.

# Codeception Test Suite Configuration

# suite for acceptance tests.
# perform tests in browser using the WebDriver or PhpBrowser.
# If you need both WebDriver and PHPBrowser tests - create a separate suite.

class_name: AcceptanceTester
modules:
    enabled:
        - PhpBrowser
        - AcceptanceHelper
    config:
        PhpBrowser:
            url: 'http://braune-digital.com'

Mit dieser Konfiguration legen wir fest, dass unsere Tests vorläufig durch PhpBrowser ausgeführt werden. PhpBrowser erlaubt das Ausführen von Tests durch einen Php Http Clienten. Javascript-Inhalte werden dabei nicht berücksichtigt. Alle Aufrufe finden relativ zu der Url braune-digital.com statt.

Jetzt ist es möglich den Test auszuführen. Dies geschieht mittels des Befehls

php ./vendor/bin/codecept run

Der Test sollte erfolgreich durchlaufen werden. Die folgende Abbildung zeigt das Ergebnis.

Leider werden Nutzer von Webinhalten diese nur in seltesten Fällen mit einem einfachen Browser ohne die Möglichkeit zur Ausführung von Javascript aufrufen. Um bei der Ausführung der Tests der Realität möglichst nahe zu kommen gibt es die Möglichkeit PhantomJS oder Selenium zu verwenden. Dies erlaubt die Ausführung von Tests mit Berücksichtigung von Javascript-Inhalten und im letzteren Fall die automatische Ausführung der Tests in gängigen Browsern wie Chrome, Firefox oder Safari.

Wir wollen für unseren Schnelleinstieg die Tests in Googles Chrome-Browser ausführen. Hierzu verwenden wir eine Instanz des Selenium-Servers als Hub und eine weitere als Node, der Tests mit einer Chrome-Instanz ausführt. Wir benötigen also den Selenium-Server und ChromeDriver, der es erlaubt einen Selenium-Node mit Chrome zu nutzen. Im Standard nutzt Selenium Mozillas Firefox. Auf einem Mac sind jetzt die folgenden Operationen notwendig.

cd /path/to/my/projects
mkdir selenium
cd selenium
wget http://selenium-release.storage.googleapis.com/2.43/selenium-server-standalone-2.43.0.jar
wget http://chromedriver.storage.googleapis.com/2.10/chromedriver_mac32.zip
unzip chromedriver_mac32.zip

Für die Ausführung von Selenium ist auf dem Server eine installierte Java-Version notwendig. Wir starten zunächst den Selenium Grid-Hub.

java -jar selenium-server-standalone-2.43.0.jar -role hub

Im Anschluss registrieren wir den ChromeDriver-Node.

java -jar ./selenium-server-standalone-2.43.0.jar -role webdriver -hub http://localhost:4444/grid/register -browser browserName="chrome",version=ANY,platform=ANY,maxInstances=5 -Dwebdriver.chrome.driver=./chromedriver

Bevor wir die Tests erneut ausführen können, muss die Codeception-Konfiguration entsprechend bearbeitet werden. Wir passen also die bereits bekannte acceptance.suite.yml wie folgt an.

# Codeception Test Suite Configuration

# suite for acceptance tests.
# perform tests in browser using the WebDriver or PhpBrowser.
# If you need both WebDriver and PHPBrowser tests - create a separate suite.

class_name: AcceptanceTester
modules:
    enabled:
        - WebDriver
        - AcceptanceHelper
    config:
        WebDriver:
            url: 'http://braune-digital.com/'
            browser: chrome
            window_size: 1920x1080
            wait: 10
            capabilities:
                unexpectedAlertBehaviour: 'accept'

Anschließend führen wir unsere Tests erneut aus.

php ./vendor/bin/codecept run

Neben er Ausgabe der beiden Selenium-Instanzen erhalten wir mit unserer neuen Konfiguration die gleiche Ausgaben. Während der Ausführung hat sich aber kurzzeitig ein Chrome-Fenster geöffnet, in dem die Tests ausgeführt wurden.

Da unsere Testmethode den Namen backendLogin trägt, werden wir den Test jetzt so anpassen, dass wir den Backend-Login in ein Typo3-Demosystem testen. Dazu passen wir unsere Datei HomeOnlineCest.php so an, dass wir in den Login-Bereich wechseln und dort das Login-Formular mit den entsprechenden Daten abschicken.

<?php
use \AcceptanceTester;

class HomeOnlineCest
{
    public function _before(AcceptanceTester $I)
    {
    }

    public function _after(AcceptanceTester $I)
    {
    }

    /**
     * Test is home available
     *
     * @param AcceptanceTester $I
     */
    public function backendLogin(AcceptanceTester $I)
    {
        $I->wantTo('check if we can login to typo3 demo backend');
        $I->amOnPage('/typo3');
        $I->see('Login');
        $I->wantTo('want to login');
        $I->fillField('username', 'admin');
        $I->fillField('p_field', 'password');
        $I->click('Login');
        $I->seeLink('Extension Manager');
    }
}

Für diesen Test passen wir ebenfalls unsere acceptance.suite.yml an.

# Codeception Test Suite Configuration

# suite for acceptance tests.
# perform tests in browser using the WebDriver or PhpBrowser.
# If you need both WebDriver and PHPBrowser tests - create a separate suite.

class_name: AcceptanceTester
modules:
    enabled:
        - WebDriver
        - AcceptanceHelper
    config:
        WebDriver:
            url: 'http://introduction.cms.demo.typo3.org/'
            browser: chrome
            window_size: 1920x1080
            wait: 10
            capabilities:
                unexpectedAlertBehaviour: 'accept'

Führen wir unseren Test jetzt mit positivem Ergebnis aus, so wissen wir, dass der Backend-Login des offiziellen Typo3-Demosystems funktionsfähig ist.

Die Möglichkeiten von Codeception übersteigen natürlich den hier aufgezeigten Rahmen. Einen guten Überblick kann man sich in der Dokumentation des Frameworks verschaffen.

© 2017, Braune Digital GmbH, Niemannsweg 69, 24105 Kiel, +49 (0) 431 55 68 63 59