Your SlideShare is downloading. ×

BDD con Behat y Mink en Symfony2

4,787

Published on

Desarrollo basado en funcionalidad (BDD) en el framework Symfony2 con las herramientas Behat y Mink

Desarrollo basado en funcionalidad (BDD) en el framework Symfony2 con las herramientas Behat y Mink

Published in: Economy & Finance, Business
0 Comments
11 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
4,787
On Slideshare
0
From Embeds
0
Number of Embeds
9
Actions
Shares
0
Downloads
99
Comments
0
Likes
11
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosCarlos Granados
  • 2. Desarrollo guiado por comportamiento (BDD)con Symfony2, Behat y Mink – Carlos Granados
  • 3. Desarrollo guiado por comportamiento (BDD)con Symfony2, Behat y Mink – Carlos Granados
  • 4. Desarrollo guiado por comportamiento (BDD)con Symfony2, Behat y Mink – Carlos Granados
  • 5. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados¿Qué es BDD?• Desarrollo basado en comportamiento funcionalidad• Pasar tests != funcionalidad conseguida• Historias en lenguaje natural y compartido• Lenguaje definido y automatizable• Las historias dirigen nuestro desarrollo• Podemos comprobar la funcionalidad
  • 6. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosHistorias (Stories)• Características (Features)• As a [role] I want [feature] so that [benefit]• Escenarios (Scenarios) y pasos (Steps)• Precondiciones (Given …)• Acciones (When…)• Resultados (Then…)
  • 7. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosFeature: Account Holder withdraws cashAs an Account HolderI want to withdraw cash from an ATMSo that I can get money when the bank is closedScenario 1: Account has sufficient fundsGiven the account balance is 100€ And the card is valid And the machine contains enough money When the Account Holder inserts the card And the Account Holder requests 20€ Then the ATM should dispense 20€ And the account balance should be 80€ And the card should be returnedScenario 2: ...
  • 8. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosGherkin• El lenguaje de cucumber• Lenguaje natural y comprensible• Lenguaje específico y definido• Lenguaje automatizable• Similar a YAML• Ficheros .feature
  • 9. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosBehat• BDD para php• Inspirado por cucumber• Herramienta de línea de comandos• Disponible en varios idiomas• Más información en http://behat.org
  • 10. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados#features/atm.featureFeature: Account Holder withdraws cashAs an Account HolderI want to withdraw cash from an ATMSo that I can get money when the bank is closedScenario: Account has sufficient fundsGiven the account balance is 100€ And the card is valid And the machine contains enough money When the Account Holder inserts the card And the Account Holder requests 20€ Then the ATM should dispense 20€ And the account balance should be 80€ And the card should be returnedScenario: ...
  • 11. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados$ behatFeature: Account Holder withdraws cashAs an Account HolderI want to withdraw cash from an ATMSo that I can get money when the bank is closedScenario 1: Account has sufficient funds #features/atm.feature:7Given the account balance is 100€ ...1 scenario ( 1 undefined)8 steps (8 undefined)You can implement undefined steps with these code snippets:/** * @Given /^the account balance is (d+)€$/ */public function theAccountBalanceIs($argument1){ throw new PendingException();}...
  • 12. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados// features/bootstrap/FeatureContext.php<?phpuse BehatBehatContextBehatContext, BehatBehatExceptionPendingException;class FeatureContext extends BehatContext{ /** * @Given /^the account balance is (d+)€$/ */ public function theAccountBalanceIs ($argument1) { throw new PendingException (); }}
  • 13. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados// features/bootstrap/FeatureContext.php<?phpuse BehatBehatContextBehatContext, BehatBehatExceptionPendingException;class FeatureContext extends BehatContext{ /** * @Given /^(?:|the )account balance is (d+)€$/ */ public function setAccountBalance ($balance) { $user = $this->getContainer()->getUser(); $account = $user->getAccount(); $account->setBalance($balance); }}
  • 14. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados$ behatFeature: Account Holder withdraws cashAs an Account HolderI want to withdraw cash from an ATMSo that I can get money when the bank is closedScenario 1: Account has sufficient funds #features/atm.feature:7Given the account balance is 100€ #featureContext::setAccountBalance()...1 scenario (1 pased)8 steps (8 passed)
  • 15. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados/** * @Then /^(?:|The )account balance should be (d+)€$/ */public function checkAccountBalance ($balance){ $user = $this->getContainer()->getUser(); $account = $user->getAccount(); if ($account->getBalance()!=$balance) { throw new Exception( Actual balance is .$account->getBalance(). € instead of .$balance.€; ); }}
  • 16. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados$ behatFeature: Account Holder withdraws cashAs an Account HolderI want to withdraw cash from an ATMSo that I can get money when the bank is closedScenario 1: Account has sufficient funds #features/atm.feature:7...And the account balance should be 80€ #featureContext::checkAccountBalance() Actual balance is 100€ instead of 80€And the card should be returned #featureContext::isCardReturned()...1 scenario (1 pased)8 steps (6 passed, 1 skipped, 1 failed)
  • 17. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granadosrequire_once PHPUnit/Autoload.php;require_once PHPUnit/Framework/Assert/Functions.php;.../** * @Then /^(?:|the )account balance should be (d+)€$/ */public function checkAccountBalance ($balance){ $user = $this->getContainer()->getUser(); $account = $user->getAccount(); assertEquals($account->getBalance(), $balance);}
  • 18. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados...Scenario: Account has insufficient fundsGiven the account balance is 10€ And the card is valid And the machine contains enough money When the Account Holder inserts the card And the Account Holder requests 20€ Then the ATM should not dispense any money And the ATM should print "Insuficient funds" And the account balance should be 10€ And the card should be returnedScenario: ...
  • 19. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosThen the account balance should be 20€/** * @Then /^the account balance should be (d+)€$/ */Then the ATM should print "Insuficient funds"/** * @Then /^the ATM should print "([^"]*)"$/ */
  • 20. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosScenario: ...Given the following users exist: | name | email | phone | | Aslak | aslak@email.com | 123 | | Joe | joe@email.com | 234 | | Bryan | bryan@email.org | 456 |/*** @Given /the following users exist:/*/public function insertUsers(TableNode $table){ $hash = $table->getHash(); foreach ($hash as $row) { $user = new User($row[name], $row[email], $row[phone]); $this->database->insert($user); }}
  • 21. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosScenario: Eat 5 out of 12 Given there are 12 cucumbers When I eat 5 cucumbers Then I should have 7 cucumbersScenario: Eat 5 out of 20 Given there are 20 cucumbers When I eat 5 cucumbers Then I should have 15 cucumbersScenario: Eat 5 out of 5 Given there are 5 cucumbers When I eat 5 cucumbers Then I should have 0 cucumbers
  • 22. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosScenario Outline: Eat cucumbers Given there are <start> cucumbers When I eat <eat> cucumbers Then I should have <left> cucumbers Examples: | start | eat | left | | 12 | 5 | 7 | | 20 | 5 | 15 | | 5 | 5 | 0 |
  • 23. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosBackground:Given the following users exist: | name | email | phone | | Aslak | aslak@email.com | 123 | | Joe | joe@email.com | 234 | | Bryan | bryan@email.org | 456 |Scenario:...Scenario:...Hooks: http://docs.behat.org/guides/3.hooks.html
  • 24. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados/** * @Then /^there should be no money in the account$/ */public function checkEmptyAccount (){ return new Then(the account balance should be 0€);}/** * @When /^the user eats and sleeps$/ */public function userEatsAndSleeps (){ return array( new When("the user eats"), new When("the user sleeps"), );}
  • 25. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosBehat en Symfony2: BehatBundle//deps[gherkin] git=https://github.com/Behat/Gherkin.git target=/behat/gherkin[behat] git=https://github.com/Behat/Behat.git target=/behat/behat[BehatBundle] git=https://github.com/Behat/BehatBundle.git target=/bundles/Behat/BehatBundle
  • 26. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados//app/autoload.php$loader->registerNamespaces(array( // .. BehatGherkin => __DIR__./../vendor/behat/gherkin/src, BehatBehat => __DIR__./../vendor/behat/behat/src, BehatBehatBundle => __DIR__./../vendor/bundles,));//app/AppKernel.phppublic function registerBundles(){ // .. if (test === $this->getEnvironment()) { $bundles[] = new BehatBehatBundleBehatBundle(); }}
  • 27. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados$ app/console -e=test behat --init @AcmeDemoBundle+Acme +DemoBundle +... +Features +Context -FeatureContext.php +...
  • 28. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados//Acme/DemoBundle/Features/Context/FeatureContext.php<?phpnamespace AcmeDemoBundleFeaturesContext;use BehatBehatBundleContextBehatContext;class FeatureContext extends BehatContext{ /** * @Given /I have a product "([^"]*)"/ */ public function insertProduct($name) { $em = $this->getContainer()->get(doctrine) ->getEntityManager(); $product = new AcmeDemoBundleEntityProduct(); $product->setName($name); $em->persist($product); $em->flush(); }}
  • 29. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosBDD en Symfony2: ejecutar tests$ app/console –e=test behat @AcmeDemoBundle
  • 30. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosPruebas de funcionalidad web: Mink• Librería php integrada con behat• Permite usar distintos Browser emulators• Controlar el Navegador• Recorrer la Página• Manipular la Página• Simular la interacción del Usuario• Interface común para todos los emuladores
  • 31. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosTipos de Browser emulators:• Emuladores Headless Browsers • Symfony Web Client • Goutte• Emuladores Browser controllers • Selenium • Sahi• Mixtos: Zombie.js
  • 32. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosControlar el Navegador// iniciar driver:$driver = new BehatMinkDriverGoutteDriver();// iniciar sesión:$session = new BehatMinkSession($driver);// arrancar sesión:$session->start();// abrir una página en el navegador:$session->visit(http://my_project.com/some_page.php);// obtener el código de respuesta:echo $session->getStatusCode();// obtener el contenido de la página:echo $session->getPage()->getContent();
  • 33. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados// utilizar la historia del navegador:$session->reload();$session->back();$session->forward();// evaluar expresión Javascript:echo $session->evaluateScript( "(function(){ return something from browser; })()");// obtener los headers:print_r($session->getResponseHeaders());// guardar cookie:$session->setCookie(cookie name, value);// obtener cookie:echo $session->getCookie(cookie name);
  • 34. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosRecorrer la Página: selectors//xpath selector$handler = new BehatMinkSelectorSelectorsHandler();$xpath = $handler->selectorToXpath(xpath, //html);//css selector$selector = new BehatMinkSelectorCssSelector();$xpath = $selector->translateToXPath(#ID);//named selectors$selector = new BehatMinkSelectorNamedSelector();$xpath = $selector->translateToXPath( array(field, id|name|value|label));//named selectors: link, button, content, select, checkbox//radio, file, optgroup, option, table
  • 35. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosRecorrer la Página: obtener elementos//obtengo la página$page = $session->getPage();//encuentro un elemento$element = $page->find(xpath, //body);//encuentro todos los elementos$elementsByCss = $page->findAll(css, .classname);//encuentro un elemento por su Id$element = $page->findById(ID);//encuentro elementos con named selectors$link = $page->findLink(href);$button = $page->findButton(name);$field = $page->findField(id);
  • 36. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosManipular la Página: Node Elements//obtengo un elemento$el = $page->find(css, .something);// obtengo el nombre del tag:echo $el->getTagName();// compruebo si tiene un atributo:$el->hasAttribute(href);// obtengo un atributo:echo $el->getAttribute(href);//obtengo el texto$plainText = $el->getText();//obtengo el html$html = $el->getHtml();
  • 37. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosManipular la Página: Form fields// marcar/desmarcar checkbox:if ($el->isChecked()) { $el->uncheck();}$el->check();// elegir option en select:$el->selectOption(optin value);// añadir un fichero:$el->attachFile(/path/to/file);// obtener el valor:echo $el->getValue();// poner un valor:$el->setValue(some val);
  • 38. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosSimular la interacción del Usuario// pulsar un botón:$el->press();//simular el ratón$el->click();$el->doubleClick();$el->rightClick();$el->mouseOver();$el->focus();$el->blur();//Hacer dragndrop$el1->dragTo($el2);
  • 39. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosIntegración con Behat: MinkContext// features/bootstrap/FeatureContext.phpuse BehatMinkBehatContextMinkContext;class FeatureContext extends MinkContext{ /** * @Then /^I press the submit button$/ */ public function PressSubmitButton() { $page = $this->getSession()->getPage(); $button = $page->findButton(submit); $button->press(); }}
  • 40. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosSteps predefinidos: Given/WhenGiven I am on "URL" When I go to "url" When I reload the page When I move backward one page When I move forward one page When I press "button" When I follow "link" When I fill in "field" with "value" When I fill in "value" for "field" When I fill in the following: When I select "option" from "select" When I additionally select "option" from "select" When I check "option" When I uncheck "option" When I attach the file "path" to "field"
  • 41. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosSteps predefinidos: ThenThen I should be on "page"Then the url should match "pattern"Then the response status code should be "code"Then the response status code should not be "code"Then I should see "text"Then I should not see "text"Then I should see "text" in the "element" elementThen the "element" element should contain "value"Then I should see an "element" elementThen I should not see an "element" elementThen the "field" field should contain "value"Then the "field" field should not contain "value"Then the "checkbox" checkbox should be checkedThen the "checkbox" checkbox should not be checkedThen I should see "num" "element" elementsThen print last response
  • 42. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados# features/search.featureFeature: Search In order to see a word definition As a website user I need to be able to search for a word Scenario: Searching for a page that does exist Given I am on "/wiki/Main_Page" When I fill in "search" with "Behavior Driven Development" And I press "searchButton" Then I should see "agile software development" Scenario: Searching for a page that does NOT exist Given I am on "/wiki/Main_Page" When I fill in "search" with "Glory Driven Development" And I press "searchButton" Then I should see “No results found"
  • 43. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados/** * @Given /^I am on the main page$/ */public function goToMainPage(){ return new Given(I am on "/wiki/Main_Page");}/** * @Then /^I press the search button$/ */public function pressSearchButton(){ return new Then(I press "searchButton");}
  • 44. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosMink en Symfony2: MinkBundle//deps[mink] git=https://github.com/Behat/Mink.git target=/behat/mink[MinkBundle] git=https://github.com/Behat/MinkBundle.git target=/bundles/Behat/MinkBundle
  • 45. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados//app/autoload.php$loader->registerNamespaces(array( // .. BehatMink => __DIR__./../vendor/behat/mink/src, BehatMinkBundle => __DIR__./../vendor/bundles,));//app/AppKernel.phppublic function registerBundles(){ // .. if (test === $this->getEnvironment()) { $bundles[] = new BehatBehatBundleBehatBundle(); $bundles[] = new BehatMinkBundleMinkBundle(); }}
  • 46. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados#app/config/config_test.ymlmink: base_url: http://localhost/app_test.php browser_name: chrome goutte: ~ sahi: ~ zombie: ~
  • 47. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados//web/app_test.phpif (!in_array(@$_SERVER[REMOTE_ADDR], array( 127.0.0.1, ::1,))) { header(HTTP/1.0 403 Forbidden); exit(You are not allowed to access this file. Check.basename(__FILE__). for more information.);}require_once __DIR__./../app/bootstrap.php.cache;require_once __DIR__./../app/AppKernel.php;use SymfonyComponentHttpFoundationRequest;$kernel = new AppKernel(test, true);$kernel->loadClassCache();$kernel->handle(Request::createFromGlobals())->send();
  • 48. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granadosnamespace AcmeDemoBundleFeaturesContext;use BehatMinkBundleContextMinkContext;class FeatureContext extends MinkContext{ /** * @When /^I go to the user account page$/ */ public function showUserAccount() { $user = $this->getContainer()->get(security.context) ->getToken()->getUser(); $session = $this->getSession(); $session->visit(/account/. $user->getSlug()); }}
  • 49. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados Qué Driver usar# symfony driver (default)@mink:symfonyScenario: ...# goutte driver@mink:goutteScenario: ...# sahi driver@mink:sahi o @javascriptScenario: ...# zombie.js driver@mink:zombieScenario: ...
  • 50. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosTrucos: Salida de Behatapp/console -e=test behat -f pretty,junit --out ,. @AcmeDemoBundle
  • 51. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosTrucos: repetir Testsapp/console -e=test behat --rerun="re.run" @AcmeDemoBundle
  • 52. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosBDD vs TDD• BDD es TDDBDD vs UnitTesting• Unit testing comprueba unidades• BDD comprueba funcionalidad
  • 53. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos GranadosStop Press!!! Behat 2.4• BehatBundle y MinkBundle deprecated• Usar MinkExtension y Symfony2Extension• Más info en http://behat.org
  • 54. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados//deps[mink] git=https://github.com/Behat/Mink.git target=/behat/mink version=v1.3.3[gherkin] git=https://github.com/Behat/Gherkin.git target=/behat/gherkin version=v2.1.1[behat] git=https://github.com/Behat/Behat.git target=/behat/behat version=v2.3.5
  • 55. Desarrollo guiado por comportamiento (BDD) con Symfony2, Behat y Mink – Carlos Granados ¡¡Gracias!! ¿Preguntas?• carlos@planetapluton.com• @carlos_granados• http://es.linkedin.com/in/carlosgranados

×