Upload
kmhusseini
View
161
Download
2
Embed Size (px)
Citation preview
E2E Tests mit PHPWartbare Automatisierte Tests mit PhpUnit, Behat, Mink und dem Page Object Pattern
Khair-ed-Din “Mozzy” HusseiniSoftware DeveloperSensioLabs Deutschland
Was sind E2E-Tests nicht?
Frontend Tests -> Domäne des Frontend TeamsDarstellung Tests -> Domäne des Design Teams
Was sind E2E Tests dann?
Tests, welche das Zusammenspiel von User Interface und dem hinterliegenden System in einem Workflow sicherstellen
Wann werden E2E-Tests eingesetzt?
UI
Unit
Manuelle Tests
Service
-> 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
-> 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
-> 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
Ambiguität aka Wischiwaschi
-> Layer Grenzen sind nicht klar-> Testdefinitionen variieren von Firma zu Firma
UI
Unit
Manuelle Tests
Service
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
Womit werden E2E-Tests geschrieben?
Verschiedene Tools verfügbar
PhpUnit, Behat, , Codeception, Atoum, Kahlan, Peridot, SimpleTest, QA-Tools etc...
Behat (BDD)
1. Features und Szenarien werden von Stakeholdern definiert2. Entwickler “übersetzen” die Szenarien in einem bestimmten
Kontext3. Komponenten werden gemockt um die Szenarien des Systems
zu simulieren4. Sukzessive Implementierung der gemockten Komponenten
Behat Szenario BeispieleScenario: Register User Success Given I am on "/register" When I fill in the following: | Username | john | | Email | [email protected] | | Password | mypassword | | Repeat Password | mypassword |
And I check "accept_tou" And I press "register_button" Then I should be on "/register/success"
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 "[email protected]" 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
-> 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
public function testRegistrationSuccess(){ $driver = new SeleniumDriver(); $session = new Session($driver);
$session->visit('http://my-project.dev/register');
$page = $session->getPage(); $registrationForm = $page->find('css', 'form.register');
$registrationForm->findField('username')->setValue('john'); $registrationForm->findField('email')->setValue('[email protected]'); $registrationForm->findField('password')->setValue('john'); $registrationForm->findField('password_repeat')->setValue('john'); $registrationForm->findField('accept_tou')->check();
$registrationForm->submit(); $page = $session->getPage(); $currentUrl = $session->getCurrentUrl(); $h1 = $page->find('css', '#content h1');
$this->assertEquals('http://my-project.dev/register/success', $currentUrl); $this->assertEquals('Registration Succeeded', $h1->getText());
$session->stop();}
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
Page Object Pattern als mögliche Lösung-> UI Abstrations Layer-> Entkoppelt UI Verhalten vom eigentlichen Test-> Entkoppelt WebDriver Implementierung vom eigentlichen Test
Behat & Page Object Pattern
-> (+) Szenario kann von Stakeholdern definiert werden-> (+)Aus 5 Steps werden 3-> (-) Stepdefinitionen müssen geschrieben werden
Scenario: Ok RegistrationGiven I visited the registration pageWhen I register with valid data for JohnThen I should be on the registration success page
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', '[email protected]', 'mypassword', 'mypassword', true);
$page = new RegistrationSuccessPage($session);$this->assertEquals($page->getUrl(), $newPage->getUrl());/** or **/$page->verifyUrl();$session->stop();}
SensioLabs BehatPageObjectExtension-> Behat Integration-> Page und Element Factory-> Konfigurierbare Namespaces-> https://github.com/sensiolabs/BehatPageObjectExtension-> Jakub Zalas https://www.github.com/jazal
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
Blackfire Player
-> https://blackfire.io/docs/player/index -> Vereinfachte Testdefinitionen durch YAML Syntax-> Szenarien können auch direkt in PHP definiert und verwendet werden-> Szenarien können wiederverwendet werden
options: endpoint: "http://gitlist.demo.blackfire.io/" title: "GitList Scenario" variables: query: foosteps: - title: Search expect: - "status_code() == 200" - "css('table.tree td').count() > 10" - "not (body() matches '/No results found./')" params: query: query submit: css('.form-search')
Blackfire Player
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
Q&A
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 "[email protected]" in xpath ".//*[@id='content']/div/div[1]/div/input[@name='email']" Then the entered email should be "[email protected]" 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!!!