End-To-End Tests in Webapplikationen können in ihrer Umsetzung komplex werden und führen schnell zu unwartbarem und fragilem Code. Der Page-Object Pattern gibt eine Möglichkeit den Code besser zu organisieren und den Spaß in automatisierte Tests zurück zu bringen.
In diesem Talk zeigt Khairi, wie das Page-Object Pattern effizient auch in funktionalen Tests umgesetzt werden kann.
Code zum Vortrag: https://github.com/mozzymoz/e2eTests
6. -> Units sind Grundsteine der Pyramide
(Methoden, Funktionen)
-> “Viele Units” bedeutet hohe
Fehleranfälligkeit
-> Units werden isoliert getestet
-> Gemockte Abhängigkeiten
-> I/O Operationen in Memory
UI
Unit
Manuelle Tests
Service
Unit Layer
7. -> Integrations und Funktionale bzw.
Komponenten Tests
-> Komponenten/Funktionale Tests:
-> Testen isolierte Komponenten
-> Externe Abhängigkeiten sind gemockt
-> Integrations Tests:
-> Testen workflows zwischen Services
und Komponenten
UI
Unit
Manuelle Tests
Service
Service Layer
8. -> E2E-Tests, die durch das UI
durchgeführt werden
-> Alle Endpunkte und Komponentent
sind voll initialisiert
-> Keine Mocks werden verwendet
UI
Unit
Manuelle Tests
Service
UI Layer
9. Ambiguität aka Wischiwaschi
-> Layer Grenzen sind nicht klar
-> Testdefinitionen variieren von Firma zu
Firma
UI
Unit
Manuelle Tests
Service
10. Recap
-> E2E Tests ergänzen Unit,
Funktionale und Integrations Tests
-> Sie decken die Fälle ab, an denen
die anderen Layer nicht rankommen,
ohne alle Endpunkte in der Ausführung zu
initialisieren
UI
Unit
Manuelle Tests
Service
11. Womit werden E2E-Tests geschrieben?
Verschiedene Tools verfügbar
PhpUnit, Behat, , Codeception, Atoum, Kahlan, Peridot,
SimpleTest, QA-Tools etc...
12. Behat (BDD)
1. Features und Szenarien werden von Stakeholdern definiert
2. Entwickler “übersetzen” die Szenarien in einem bestimmten Kontext
3. Komponenten werden gemockt um die Szenarien des Systems zu
simulieren
4. Sukzessive Implementierung der gemockten Komponenten
13. Behat Szenario Beispiele
Scenario: Register User Success
Given I am on "/register"
When I fill in the following:
| Username | john |
| Email | john@example.com |
| Password | mypassword |
| Repeat Password | mypassword |
And I check "accept_tou"
And I press "register_button"
Then I should be on "/register/success"
14. Scenario: Bad Registration
Given I load test data configured in "site_data.yml"
And I am on "/register"
When I fill in "username" with "john"
And I fill in "email" with "john@example.com"
And I fill in "password" with "mypassword"
And I fill in "password_repeat" with "mypassword"
And I check "accept_tou"
And I press "register_button"
Then I should be on "/register/success"
And I should see "Registration Succeeded" in the "#content h1" element
10 steps
15. -> Testframework Instanz der xUnit Architektur
-> Bietet Tools und Bibliotheken für alle möglichen Arten von Tests an
-> E2E-Tests werden durch Webdriver u.ä. ermöglicht (z.B. Mink,
Facebook Webdriver)
PhpUnit
17. Probleme bei der Implementierung der E2E-Tests
-> Implementationsdetails sind in den Vordergrund geschoben
-> Behat Szenario nicht ganz vom Stakeholder verstanden
-> Testfälle sind aufgebläht
-> Tests werden mit der Zeit schwer wartbar
-> Frustrationen führen zur Häufung von manuellen Tests
18. Page Object Pattern als mögliche Lösung
-> UI Abstrations Layer
-> Entkoppelt UI Verhalten vom eigentlichen Test
-> Entkoppelt WebDriver Implementierung
vom eigentlichen Test
19.
20. Behat & Page Object Pattern
-> (+) Szenario kann von Stakeholdern
definiert werden
-> (+)Aus 5 Steps werden 3
-> (-) Stepdefinitionen müssen geschrieben
werden
Scenario: Ok Registration
Given I visited the registration page
When I register with valid data for John
Then I should be on the registration
success page
21. PHPUnit & Page Object Pattern
-> (+) Szenario kann von Stakeholdern
definiert werden
-> (+)Aus 5 Steps werden 3
-> (-) Stepdefinitionen müssen geschrieben
werden
public function testRegistrationSuccess()
{
$driver = new SeleniumDriver();
$session = new Session($driver);
$page = new RegistrationPage($session);
$page->open();
$page->verifyUrl();
$newPage = $page->register('john', 'john@example.com', 'mypassword', 'mypassword', true);
$page = new RegistrationSuccessPage($session);
$this->assertEquals($page->getUrl(), $newPage->getUrl());
/** or **/
$page->verifyUrl();
$session->stop();
}
22. SensioLabs BehatPageObjectExtension
-> Behat Integration
-> Page und Element Factory
-> Konfigurierbare Namespaces
-> https://github.com/sensiolabs/BehatPageObjectExtension
-> Jakub Zalas https://www.github.com/jazal
23. BehatPageObjectExtension & Symfony
-> Factories können in Symfony DIC integriert werden
-> BrowserKit kann als Mink-Driver verwendet werden
-> Page Objekte können mit Funktionalen Tests geteilt werden
-> Da ist schon was vorbereitet :)
https://github.com/mozzymoz/e2eTests
26. Recap
-> POP kapselt viel vom eigentlichen Test ab
-> Tests werden durch Entkoppelung stabiler
-> Neuer Layer bedeuted ein wenig mehr Code zu schreiben
-> Umsetzung kann noch vereinfacht werden
-> Vor allem KISS
29. Scenario: Worse eva Registration
Given I load test data configured in "site_data.yml"
And I am on "/register"
When I enter "John" in xpath ".//*[@id='register_form']/div/div[1]/div/input[@name='username']"
Then the entered username should be "John"
When I enter "john.doe@example.com" in xpath ".//*[@id='content']/div/div[1]/div/input[@name='email']"
Then the entered email should be "john.doe@example.com"
When I enter "mypassword" in xpath ".//*[@id='register_form']/div/div[1]/div/input[@name='password']"
Then the entered password should be "mypassword"
When I enter "mypassword" in xpath ".//*[@id='register_form']/div/div[1]/div/input[@name='password_repeat']"
Then the entered repeated password should be "mypassword"
When I click element in xpath ".//*[@id='register_form']/div/div[1]/div/input[@name='accept_tou']"
Then the terms of use should be "accepted"
When I click element in xpath ".//*[@id='register_form']/div/div[1]/div/input[@name='register_button']"
Then I should be on "/register/success"
And I should see the text "Registration Succeeded" in xpath ".//*[@id='content']/h1" 15 steps!!!
Hinweis der Redaktion
E2E Tests werden oft mit Frontend und Darstellungstests gleichgestellt
-> sind ganz andere Tests
Frontendtests
-> haben ihre eigenen Unit und Funktionalentests
Darstellung Tests
-> schwierig und in einigen Fällen unmöglich umzusetzen, je nach dem wieviele verschiedenen Geräte man abdecken möchte
End to End heißt hier vom Anfang des Workflows (Systemendpunktübergreifend) zum Ende.
Mike Cohn: Succeeding with Agile
Dateisystem Operationen: mikey179/vfsStream -> php stream wrapper um file_* funktionen in memory zu halten
Blackbox bereich
Units->Komponenten->Services
-> Wort UI ist irreführend da E2E Tests auch APIs betreffen können
-> sollten nicht mehr als 10% aller tests sein
Alister Scott -> in his post “Yet another software testing pyramid”1-> only two sections, “Business Facing Tests” and “Technology facing Tests”.
Google uses small medium large