End-to-End-Tests mit Protractor

GUI-Tests sind bei der Entwicklung qualitativ hochwertiger Webanwendungen eine gute Ergänzung zu Unit-Tests. Mit Protractor stellt Google ein speziell auf das AngularJS-Webframework abgestimmtes Werkzeug bereit.

In Pocket speichern vorlesen Druckansicht
Lesezeit: 12 Min.
Von
  • Benjamin Schmid
Inhaltsverzeichnis

GUI-Tests sind bei der Entwicklung qualitativ hochwertiger Webanwendungen eine gute Ergänzung zu Unit-Tests. Mit Protractor stellt Google ein speziell auf das AngularJS-Webframework abgestimmtes Werkzeug bereit.

AngularJS macht es vor: Moderne Webanwendungen laufen inzwischen vollständig im Browser ab, laden
dank Single-Page-Architektur Inhalte im Hintergrund statt über neue Seiten und nutzen HTML5, um sich auf dem Desktop und mobilen Endgeräten zu präsentieren. Wenn es ums Testen geht, stellt Googles Framework dem Entwickler mit modularer Strukturierung über Services, Dependency Injection und Mocks für Server-Zugriffe bereits viele Hilfsmittel für solide und effiziente Unit-Tests zur Seite.

Oberflächentests sind eine gute Ergänzung, denn mit ihnen lässt sich die Anwendung aus der Sicht des Anwenders überprüfen. Idealerweise führt man sie automatisiert aus und nutzt echte Browser und Endgeräte. Als De-facto-Standard hat sich zu dem Zweck Selenium einen Namen gemacht. Das Tool simuliert über eine API die Aktivitäten eines Nutzers ferngesteuert auf allen relevanten Browsern.

In der Praxis kommt Selenium jedoch selten direkt zum Einsatz, denn das Erstellen stabiler GUI-Tests stellt sich als mühsame und fehlerträchtige Angelegenheit dar. Single-Page-Anwendungen bringen eine zusätzliche Schwierigkeitsstufe mit: Durch das fehlende Neuladen der Seite entfällt ein wichtiges Signal dafür, dass die ausgelöste Aktivität abgeschlossen ist und sich der Testlauf fortsetzen lässt. Um zu einer stabil funktionierenden Testlösung zu kommen, war es daher lange Zeit Standard, eigene Abstraktionsschichten zu bauen.

Auch Protractor setzt auf der bewährten WebDriver-API von Selenium auf und verpackt sie in das BDD-Testframeworks (Behaviour Driven Development) Jasmine. Derzeit noch experimentelle Unterstützung gibt es zudem für die beiden anderen BDD-Frameworks Mocha und Cucumber. Als Schwesterprojekt von AngularJS hat Protractor fundiertes Wissen über Internas und bietet daher einen schnellen Einstieg in die Entwicklung praxisnaher Oberflächentests.

So kann der sonst übliche Code für zusätzliche Wartezeiten und Aktivitätsprüfungen entfallen. Protractor erkennt automatisch den Moment, an dem AngularJS alle Aufgaben zum Abschluss gebracht hat und die Seite vollständig synchronisiert ist. Angular-spezifische Locator-Strategien vereinfachen eine weitere Kernaufgabe: das Identifizieren und Wiederfinden einzelner GUI-Elemente auf der Website. Trotz derartiger Komfortfunktionen hat man aber stets vollen Zugriff auf die WebDriver-API und ihre Freiheiten. Dadurch ist ein Einsatz von Protractor auch in Umgebungen denkbar, die nicht mit AngularJS arbeiten.

Bevor man Protractor nutzen kann, ist das Tool mit dem Befehl npm install -g protractor über den Node.js-Paketmanager zu installieren. Im Anschluss lädt man via webdriver-manager update noch die plattformspezifischen Browser-Anbindungen nach. Nun lässt sich der Selenium-Server über webdriver-manager start starten. Damit das aber gelingt, müssen zudem Java und die gewünschten Zielbrowser installiert sein.

Eine Konfigurationsdatei teilt Protractor nun mit, wo der Selenium-Server und die Tests zu finden und welche Browser zu verwenden sind. Im vorliegenden Beispiel sind das Chrome und Firefox:

// protractor-conf.js
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['*.e2e.js'],
multiCapabilities: [
{ browserName: 'firefox' },
{ browserName: 'chrome' }
]
}

Der erste einfache Testfall soll eine Taschenrechner-Beispielanwendung testen. Mit protractor protractor-conf.js läßt sich der Test nun direkt mit Protractor ausführen.

// webcalculator.e2e.js
describe('Web Calculator', function() {
it('should have a page title & Go! button', function() {
browser.get('https://juliemr.github.io/protractor-demo/');

expect(browser.getTitle()).toEqual('Super Calculator');
expect(element(by.buttonText('Go!')).isDisplayed()).toBeTruthy();
});
});