Behat in BDD
Piotr Pelczar
me@athlan.pl
MPZ, 17 gru 2014
BDD – Behaviour Driven Development
• TDD - Test-driven Design
• DDD - Domain-driven Design
• Grupa deweloperów i ludzi od biznesu mają te same
narzędzia do definiowania wymagań.
BDD
• Grupa deweloperów i ludzi od biznesu mają te same
narzędzia do definiowania wymagań.
Czyli pisanie scenariuszy:
Gherkin language
Potrzeba biznesowa
Feature: Homepage
In order to keep my notes organized
As an authenticated user
I need to be able to see my notebooks list
Potrzeba biznesowa
Feature: Homepage
In order to keep my notes organized
As an authenticated user
I need to be able to see my notebooks list
Potrzeba biznesowa
Feature: Homepage
In order to keep my notes organized
As an authenticated user
I need to be able to see my notebooks list
Potrzeba biznesowa
Feature: Homepage
In order to keep my notes organized
As an authenticated user
I need to be able to see my notebooks list
Potrzeba biznesowa
Feature: Homepage
In order to keep my notes organized
As an authenticated user
I need to be able to see my notebooks list
Potrzeba biznesowa - scenariusz
Scenario: Anonymous user should not be able to view
notebook list
Given I am anonymous user
When I click "Go to notebooks"
And I go to "/notebooks/"
Then I should be redirected to "/login"
Potrzeba biznesowa - scenariusz
Scenario: User should can update notebook
and be redirected to notebook tasks
Given I am authenticated as "Greg"
And I go to "/notebooks/"
And I follow "Edit Todo list"
And I fill in "notebook_name" with "Shopping list
edited"
And I press "Submit"
Then I should see success message "The notebook has
been updated successfully"
And should be redirected to "/notebooks/(.+)"
Potrzeba biznesowa – kilka scenariuszy
Background:
Given there are following users:
| username | password |
| Greg | a |
| Katie | a |
Gherkin - składnia
• Feature
• opis ogólny
• Tagi
• Background
• Given
• Zestaw Scenariuszy
• Given
• When
• Then
Zalety
• Forma czytelna dla człowieka biznesu
• Forma czytelna dla programistów
• Dokumentacja dla nowych osób w projekcie – profit!
Zalety
• Wszystko jest na papierze
• Scenariusze są powtarzalne
• Służą jako automatycznie wykonywane cylicznie testy
• Scenariusze są w postaci tekstowej, zatem można je
wersjonować, np. na git
Wady
• Narzut czasowy na produkowanie scenariuszy
• Tworzenie słownika pojęć (FeatureContext)
• Czas trwania testów
ale…
• zrównolegnienie wielowątkowe
• wykonywanie tylko pewnego podzbioru testów
• testy wykonywane asynchronicznie na serwerze CI
TDD i BDD w Scrum
• Można przyjąć jako kryterium akceptacji
• Może stanowić standard do każdej iteracji
• Trzeba dodatkowo szacować
Contineous Integration
• Automatyczne uruchamianie po każdym commicie na
serwerze Contineous Integration
• W przypadku błedu mail do wybranych osób z
powiadomieniem, kto popsuł 
• Eliminacja „u mnie działa”
• Narzędzia: Jenkins/Hudson
Behat
Behat - Uruchamianie
behat
behat --tags name
inaczej:
bin/behat
php behat.phar
Behat - Scenaiusze
• Scenariusze w plikach .feature
• Oznaczone tagiem @nazwatagu
Behat - FeatureContext
• Scenariusze są wykonywane w ramach kontekstów
FeatureContext
• FeatureContext to zbiór definicji Given/When/Then,
to tutaj dokonuje się interpretacja zdań na kod
Behat - FeatureContext
class MinkContext extends RawMinkContext implements
TranslatableContext
{
/**
* Opens specified page.
*
* @Given /^(?:|I )am on "(?P<page>[^"]+)"$/
* @When /^(?:|I )go to "(?P<page>[^"]+)"$/
*/
public function visit($page)
{
$this->visitPath($page);
}
Behat - FeatureContext
/**
* Clicks link with specified id|title|alt|text.
*
* @When /^(?:|I )follow
"(?P<link>(?:[^"]|")*)"$/
*/
public function clickLink($link)
{
$link = $this->fixStepArgument($link);
$this->getSession()->getPage()-
>clickLink($link);
}
Behat - FeatureContext
/**
* @Then /^(?:|I )should see "([^"]+)"
(heading|headline)$/
*/
public function iShouldSeeHeading($heading)
{
$this->assertSession()
->elementTextContains(
'xpath', '//h1 | //h2',
$this->fixStepArgument($heading));
}
Behat – FeatureContext - XPATH
/**
* @Then /^(?:|I )should see
(?P<type>[(error|success|info|warning)]+)
message "(?P<message>[^"]+)"$/
*/
public function iShouldSeeMessage($type,
$message)
{
$this->assertSession()
->elementTextContains('xpath',
'//div[@class="alert alert-' . $type .
'"]', $this->fixStepArgument($message));
}
Behat - Suites
• Scenariusze oraz FeatureContext w ramach których się
wykonują to suites definiowane w pliku głównym
behat.yml
Suites
Ścieżki z plikami .features
(lista)
FeatureContext’y
(lista)
Behat – Konfiguracja testowania
• Całkowicie poza aplikacją – klikanie po UI
• Wartość dodana: tekstowe Selenium
• Całkowicie w aplikacji
• Czyste DDD, prawie testy jednostkowe Core Domain
• Mieszane
• Największa wartość – co się dzieje w systemie, gdy klikam
po UI lub wysyłam requesty do API
Behat – Konfiguracja testowania
• Integracja z frameworkiem wymaga bardzo dużej
wiedzy technicznej odnośnie wykorzystywanego
narzędzia.
• Dependency Injection i Inversion of Control
• Sessions
• Repositories/Database/Serial buses
Behat – Konfiguracja testowania
• Integracja z frameworkiem
Przykład: Doctrine Fixtures
/**
* @BeforeScenario
*/
public function
loadFixturesBeforeScenarios() {
$paths = array();
foreach ($this->kernel->getBundles()
as $bundle) {
$paths[] = $bundle-
>getPath().'/DataFixtures/ORM';
}
$loader = new
DataFixturesLoader($this->getContainer());
foreach ($paths as $path) {
if (is_dir($path)) {
$loader-
>loadFromDirectory($path);
}
}
$em = $this->getContainer()-
>get('doctrine.orm.entity_manager');
$fixtures = $loader->getFixtures();
$purger = new ORMPurger($em);
//$purger->setPurgeMode($input-
>getOption('purge-with-truncate') ?
ORMPurger::PURGE_MODE_TRUNCATE :
ORMPurger::PURGE_MODE_DELETE);
$purger-
>setPurgeMode(ORMPurger::PURGE_MODE_DELETE
);
$executor = new ORMExecutor($em,
$purger);
$append = false;
$executor->execute($fixtures,
$append);
}
Behat – Architektura
• Napisany w PHP
• Uruchamiany z CLI
• Wykorzystuje abstrakcyjną przeglądarkę (wykorzystuje API):
• Selenium (obsługa Javascipt, CSS, AJAX)
• Mink (prosta, szybsza)
Behat – Alternatywy
• Do klikania można wykorzystać wszędzie
• Cucumber – Ruby (inspiracja)
http://cukes.info/
• Robot – Java
http://robotframework.org/
• SpecFlow - .NET
http://www.specflow.org/
Dzięki!
Q&A?
Piotr Pelczar
me@athlan.pl

[BDD] Introduction to Behat (PL)

  • 1.
    Behat in BDD PiotrPelczar me@athlan.pl MPZ, 17 gru 2014
  • 2.
    BDD – BehaviourDriven Development • TDD - Test-driven Design • DDD - Domain-driven Design • Grupa deweloperów i ludzi od biznesu mają te same narzędzia do definiowania wymagań.
  • 3.
    BDD • Grupa deweloperówi ludzi od biznesu mają te same narzędzia do definiowania wymagań. Czyli pisanie scenariuszy:
  • 4.
  • 5.
    Potrzeba biznesowa Feature: Homepage Inorder to keep my notes organized As an authenticated user I need to be able to see my notebooks list
  • 6.
    Potrzeba biznesowa Feature: Homepage Inorder to keep my notes organized As an authenticated user I need to be able to see my notebooks list
  • 7.
    Potrzeba biznesowa Feature: Homepage Inorder to keep my notes organized As an authenticated user I need to be able to see my notebooks list
  • 8.
    Potrzeba biznesowa Feature: Homepage Inorder to keep my notes organized As an authenticated user I need to be able to see my notebooks list
  • 9.
    Potrzeba biznesowa Feature: Homepage Inorder to keep my notes organized As an authenticated user I need to be able to see my notebooks list
  • 10.
    Potrzeba biznesowa -scenariusz Scenario: Anonymous user should not be able to view notebook list Given I am anonymous user When I click "Go to notebooks" And I go to "/notebooks/" Then I should be redirected to "/login"
  • 11.
    Potrzeba biznesowa -scenariusz Scenario: User should can update notebook and be redirected to notebook tasks Given I am authenticated as "Greg" And I go to "/notebooks/" And I follow "Edit Todo list" And I fill in "notebook_name" with "Shopping list edited" And I press "Submit" Then I should see success message "The notebook has been updated successfully" And should be redirected to "/notebooks/(.+)"
  • 12.
    Potrzeba biznesowa –kilka scenariuszy Background: Given there are following users: | username | password | | Greg | a | | Katie | a |
  • 13.
    Gherkin - składnia •Feature • opis ogólny • Tagi • Background • Given • Zestaw Scenariuszy • Given • When • Then
  • 14.
    Zalety • Forma czytelnadla człowieka biznesu • Forma czytelna dla programistów • Dokumentacja dla nowych osób w projekcie – profit!
  • 15.
    Zalety • Wszystko jestna papierze • Scenariusze są powtarzalne • Służą jako automatycznie wykonywane cylicznie testy • Scenariusze są w postaci tekstowej, zatem można je wersjonować, np. na git
  • 16.
    Wady • Narzut czasowyna produkowanie scenariuszy • Tworzenie słownika pojęć (FeatureContext) • Czas trwania testów ale… • zrównolegnienie wielowątkowe • wykonywanie tylko pewnego podzbioru testów • testy wykonywane asynchronicznie na serwerze CI
  • 17.
    TDD i BDDw Scrum • Można przyjąć jako kryterium akceptacji • Może stanowić standard do każdej iteracji • Trzeba dodatkowo szacować
  • 18.
    Contineous Integration • Automatyczneuruchamianie po każdym commicie na serwerze Contineous Integration • W przypadku błedu mail do wybranych osób z powiadomieniem, kto popsuł  • Eliminacja „u mnie działa” • Narzędzia: Jenkins/Hudson
  • 19.
  • 20.
    Behat - Uruchamianie behat behat--tags name inaczej: bin/behat php behat.phar
  • 21.
    Behat - Scenaiusze •Scenariusze w plikach .feature • Oznaczone tagiem @nazwatagu
  • 22.
    Behat - FeatureContext •Scenariusze są wykonywane w ramach kontekstów FeatureContext • FeatureContext to zbiór definicji Given/When/Then, to tutaj dokonuje się interpretacja zdań na kod
  • 23.
    Behat - FeatureContext classMinkContext extends RawMinkContext implements TranslatableContext { /** * Opens specified page. * * @Given /^(?:|I )am on "(?P<page>[^"]+)"$/ * @When /^(?:|I )go to "(?P<page>[^"]+)"$/ */ public function visit($page) { $this->visitPath($page); }
  • 24.
    Behat - FeatureContext /** *Clicks link with specified id|title|alt|text. * * @When /^(?:|I )follow "(?P<link>(?:[^"]|")*)"$/ */ public function clickLink($link) { $link = $this->fixStepArgument($link); $this->getSession()->getPage()- >clickLink($link); }
  • 25.
    Behat - FeatureContext /** *@Then /^(?:|I )should see "([^"]+)" (heading|headline)$/ */ public function iShouldSeeHeading($heading) { $this->assertSession() ->elementTextContains( 'xpath', '//h1 | //h2', $this->fixStepArgument($heading)); }
  • 26.
    Behat – FeatureContext- XPATH /** * @Then /^(?:|I )should see (?P<type>[(error|success|info|warning)]+) message "(?P<message>[^"]+)"$/ */ public function iShouldSeeMessage($type, $message) { $this->assertSession() ->elementTextContains('xpath', '//div[@class="alert alert-' . $type . '"]', $this->fixStepArgument($message)); }
  • 27.
    Behat - Suites •Scenariusze oraz FeatureContext w ramach których się wykonują to suites definiowane w pliku głównym behat.yml Suites Ścieżki z plikami .features (lista) FeatureContext’y (lista)
  • 28.
    Behat – Konfiguracjatestowania • Całkowicie poza aplikacją – klikanie po UI • Wartość dodana: tekstowe Selenium • Całkowicie w aplikacji • Czyste DDD, prawie testy jednostkowe Core Domain • Mieszane • Największa wartość – co się dzieje w systemie, gdy klikam po UI lub wysyłam requesty do API
  • 29.
    Behat – Konfiguracjatestowania • Integracja z frameworkiem wymaga bardzo dużej wiedzy technicznej odnośnie wykorzystywanego narzędzia. • Dependency Injection i Inversion of Control • Sessions • Repositories/Database/Serial buses
  • 30.
    Behat – Konfiguracjatestowania • Integracja z frameworkiem Przykład: Doctrine Fixtures
  • 31.
    /** * @BeforeScenario */ public function loadFixturesBeforeScenarios(){ $paths = array(); foreach ($this->kernel->getBundles() as $bundle) { $paths[] = $bundle- >getPath().'/DataFixtures/ORM'; } $loader = new DataFixturesLoader($this->getContainer()); foreach ($paths as $path) { if (is_dir($path)) { $loader- >loadFromDirectory($path); } } $em = $this->getContainer()- >get('doctrine.orm.entity_manager'); $fixtures = $loader->getFixtures(); $purger = new ORMPurger($em); //$purger->setPurgeMode($input- >getOption('purge-with-truncate') ? ORMPurger::PURGE_MODE_TRUNCATE : ORMPurger::PURGE_MODE_DELETE); $purger- >setPurgeMode(ORMPurger::PURGE_MODE_DELETE ); $executor = new ORMExecutor($em, $purger); $append = false; $executor->execute($fixtures, $append); }
  • 32.
    Behat – Architektura •Napisany w PHP • Uruchamiany z CLI • Wykorzystuje abstrakcyjną przeglądarkę (wykorzystuje API): • Selenium (obsługa Javascipt, CSS, AJAX) • Mink (prosta, szybsza)
  • 33.
    Behat – Alternatywy •Do klikania można wykorzystać wszędzie • Cucumber – Ruby (inspiracja) http://cukes.info/ • Robot – Java http://robotframework.org/ • SpecFlow - .NET http://www.specflow.org/
  • 34.