29
E2E Tests mit PHP Wartbare Automatisierte Tests mit PhpUnit, Behat, Mink und dem Page Object Pattern

E2E Tests mit PHP

Embed Size (px)

Citation preview

Page 1: E2E Tests mit PHP

E2E Tests mit PHPWartbare Automatisierte Tests mit PhpUnit, Behat, Mink und dem Page Object Pattern

Lukas Sadzik
Ein Codebeispiel sagt mehr als 1000 Worte ;) (Wie sieht das aus, wenn sich funktionale (SFWebTestCase) Tests PageObjects mit E2E Test teilen?)
Khair-ed-Din Husseini
Hier kommen noch ein paar slides dazu.Evtl. lagert Jakub Z. die PageObjekte von der Behat Extension im Dezember, damit wollte ich dann anfangen den Pattern auf die WebTestCases zu übertragen.Dazu hier mehr: https://github.com/sensiolabs/BehatPageObjectExtension/issues/61Aber auch wenn es zeitlich nicht hin haut, wollte ich ein Beispiel schreiben, in dem ich die Extension in composer reinhole und nur den Pattern und die Factories benutze
Lukas Sadzik
Macht es Sinn, ein Beispiel für die behat.yml zu zeigen? (Wenns sehr einfach ist, demonstriert man, dass es einfach ist, wenns nicht trivial ist, kann man Fallstricke zeigen)
Page 2: E2E Tests mit PHP

Khair-ed-Din “Mozzy” HusseiniSoftware DeveloperSensioLabs Deutschland

Page 3: E2E Tests mit PHP

Was sind E2E-Tests nicht?

Frontend Tests -> Domäne des Frontend TeamsDarstellung Tests -> Domäne des Design Teams

Page 4: E2E Tests mit PHP

Was sind E2E Tests dann?

Tests, welche das Zusammenspiel von User Interface und dem hinterliegenden System in einem Workflow sicherstellen

Page 5: E2E Tests mit PHP

Wann werden E2E-Tests eingesetzt?

UI

Unit

Manuelle Tests

Service

Page 6: E2E Tests mit PHP

-> 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

Page 7: E2E Tests mit PHP

-> 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

Page 8: E2E Tests mit PHP

-> 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

Page 9: E2E Tests mit PHP

Ambiguität aka Wischiwaschi

-> Layer Grenzen sind nicht klar-> Testdefinitionen variieren von Firma zu Firma

UI

Unit

Manuelle Tests

Service

Page 10: E2E Tests mit PHP

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

Page 11: E2E Tests mit PHP

Womit werden E2E-Tests geschrieben?

Verschiedene Tools verfügbar

PhpUnit, Behat, , Codeception, Atoum, Kahlan, Peridot, SimpleTest, QA-Tools etc...

Page 12: E2E Tests mit PHP

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

Page 13: E2E Tests mit PHP

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"

Page 14: E2E Tests mit PHP

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

Page 15: E2E Tests mit PHP

-> 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

Page 16: E2E Tests mit PHP

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();}

Page 17: E2E Tests mit PHP

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 18: E2E Tests mit PHP

Page Object Pattern als mögliche Lösung-> UI Abstrations Layer-> Entkoppelt UI Verhalten vom eigentlichen Test-> Entkoppelt WebDriver Implementierung vom eigentlichen Test

Page 19: E2E Tests mit PHP
Page 20: E2E Tests mit PHP

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

Page 21: E2E Tests mit PHP

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();}

Page 22: E2E Tests mit PHP

SensioLabs BehatPageObjectExtension-> Behat Integration-> Page und Element Factory-> Konfigurierbare Namespaces-> https://github.com/sensiolabs/BehatPageObjectExtension-> Jakub Zalas https://www.github.com/jazal

Page 23: E2E Tests mit PHP

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

Page 24: E2E Tests mit PHP

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

Page 25: E2E Tests mit PHP

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

Page 26: E2E Tests mit PHP

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

Page 27: E2E Tests mit PHP
Page 28: E2E Tests mit PHP

Q&A

Page 29: E2E Tests mit PHP

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!!!