behat в php с использованием behat и mink

53
BDD в PHP с использованием Behat и Mink

Upload: tyomo4ka

Post on 29-Nov-2014

4.162 views

Category:

Technology


1 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Behat в PHP с использованием Behat и Mink

BDD в PHP с использованием

Behat и Mink

Page 2: Behat в PHP с использованием Behat и Mink

About me

• Symfony developer at KnpLabs

• twitter: @tyomo4ka

• GitHub: tyomo4ka

Page 3: Behat в PHP с использованием Behat и Mink

Happy Awesome Developers

Page 4: Behat в PHP с использованием Behat и Mink

Agenda

• BDD

• Gherkin DSL

• Behat

• Mink

• BDD workflow

Page 5: Behat в PHP с использованием Behat и Mink

Зачем тестировать?

• Безопасный рефакторинг• Отсутствие регрессий• Более качеcтвенная архитектура• Уменьшение числа багов• Степень зрелости разработчика?

Page 6: Behat в PHP с использованием Behat и Mink

Behavior Driven Development

Page 7: Behat в PHP с использованием Behat и Mink

TDD

• TDD не очень удачое название

• Если мы пишем тесты перед кодом, мы все равно думаем об архитектуре

• Design Driven Development?

Page 8: Behat в PHP с использованием Behat и Mink

TDD и BDD

• Также пишем тесты перед кодом

• При TDD мы фиксируем в тестах архитектуру приложения или его частей

• При BDD мы фиксируем в тестах поведение приложения или его частей

• Описательная часть: спецификация или пользовательские сценарии

Page 9: Behat в PHP с использованием Behat и Mink

Spec BDD

• Добавляем описательную часть к тестам

• Получаем не тесты, а спецификации объектов

• Тестирование системы изнутри

• Используем вместо юнит тестов и интеграционых тестов

Page 10: Behat в PHP с использованием Behat и Mink

Story (Scenario) BDD

• Вместо тестов описываем шаги, которые нужно выполнить для достижения определнного результата

• Шаги должны легко читаться, в идеале это должны быть простые предложения

• Тестирование системы снаружи

• Замена функциональным тестам

Page 11: Behat в PHP с использованием Behat и Mink

Gherkin DSL

Page 12: Behat в PHP с использованием Behat и Mink

Feature: Customer login In order to view protected data As a customer I need to be able to login

Background: Given customers are registered: | username | password | blocked | | [email protected] | password | no | | [email protected] | password | yes |

Scenario: Successful login Given I am on page "Login" When I fill in "Username" with "[email protected]" And I fill in "Password" with "password" And I press "Submit" Then I should be on page "Personal profile" And I should see "Successful login"

Page 13: Behat в PHP с использованием Behat и Mink

Feature: Название функционала In order to ... Ценность функционала As a ... Выгодополучатель I need ... Краткое описание функционала

Background: Given ... Начальное состояние системы

Scenario: Название сценария Given ... Начальное состояние And ... Начальное состояние When ... Выполняем шаг And ... Выполняем шаг Then ... Проверяем результат And ... Проверяем результат

Page 14: Behat в PHP с использованием Behat и Mink

Behat

Page 15: Behat в PHP с использованием Behat и Mink

Зачем?

• A php framework for testing your business expectations

Page 16: Behat в PHP с использованием Behat и Mink

Установка

• PHP 5.3

• Composer

• PHAR

• Git

Page 17: Behat в PHP с использованием Behat и Mink

Инициализация

• behat --init

• features/ directory

• features/bootstrap/ directory

• features/bootstrap/*Context.php

• behat.yml

Page 18: Behat в PHP с использованием Behat и Mink

features/*.feature

• Gherkin DSL

• behat --story-syntax --lang=LANG

Page 19: Behat в PHP с использованием Behat и Mink

[Feature|Business Need|Ability]: Internal operations In order to stay secret As a secret organization We need to be able to erase past agents' memory

Background: Given there is agent A And there is agent B

Scenario: Erasing agent memory Given there is agent J And there is agent K When I erase agent K's memory Then there should be agent J But there should not be agent K

[Scenario Outline|Scenario Template]: Erasing other agents' memory Given there is agent <agent1> And there is agent <agent2> When I erase agent <agent2>'s memory Then there should be agent <agent1> But there should not be agent <agent2>

[Examples|Scenarios]: | agent1 | agent2 | | D | M |

Page 20: Behat в PHP с использованием Behat и Mink

Feature:  Listing  developers    As  a  Visitor    I  want  to  browse  through  developers  list

   Background:        Given  the  site  has  following  users:        |  name            |        |  knplabs      |        |  fos              |        Given  the  site  has  following  bundles:        |  username    |  name              |  description  |  lastCommitAt  |  score  |  trend1  |        |  knplabs      |  TestBundle  |  test  desc      |-­‐1  day                |  10        |  15          |        |  fos              |  UserBundle  |  user  desc      |-­‐2  days              |  20        |  5            |

   Scenario:  Listing  developers        When  I  go  to  "/"        And  I  follow  "Developers"        Then  I  should  see  "2  developers  using  Symfony2"        And  I  should  see  "knplabs"  developer        And  I  should  see  "fos"  developer

Page 21: Behat в PHP с использованием Behat и Mink

Context

• POPO

• Описание шагов• Хуки• Subcontexts

• Closures для описания шагов и хуков

Page 22: Behat в PHP с использованием Behat и Mink

       public  function  __construct($kernel)        {                $this-­‐>useContext('symfony_doctrine',  new  SymfonyDoctrineContext());                $this-­‐>useContext('solr',  new  SolrContext());                $this-­‐>useContext('mink',  new  MinkContext());                $this-­‐>useContext('api',  new  ApiContext());        }

Page 23: Behat в PHP с использованием Behat и Mink

Steps definition

• @Given, @When, @Then

• Если шаг не выбросил исключение, значит он завершился успешно

• Нет своих асершенов, но легко можно использовать асершены из PHPUnit

Page 24: Behat в PHP с использованием Behat и Mink

       /**          *  @Given  /^the  bundles  have  following  keywords:$/          */        public  function  theBundlesHaveFollowingKeywords(TableNode  $table)        {                $entityManager  =  $this-­‐>getEntityManager();

               foreach  ($table-­‐>getHash()  as  $row)  {                        if  (isset($this-­‐>bundles[$row['bundle']]))  {                                $bundle  =  $this-­‐>bundles[$row['bundle']];                                $keyword  =  $entityManager

-­‐>getRepository('Knp\Bundle\KnpBundlesBundle\Entity\Keyword')-­‐>findOrCreateOne($row['keyword']);

                               $bundle-­‐>addKeyword($keyword);                                $entityManager-­‐>persist($bundle);                        }                }

               $entityManager-­‐>flush();        }

Page 25: Behat в PHP с использованием Behat и Mink

Hooks

• BeforeStep/AfterStep

• BeforeScenario/AfterScenario

• BeforeFeature/AfterFeature

• BeforeSuite/AfterSuite

• Hooks can be tagged

Page 26: Behat в PHP с использованием Behat и Mink

       /**          *  @BeforeScenario          *          *  @return  null          */        public  function  buildSchema($event)        {                $metadata  =  $this-­‐>getMetadata();

               if  (!empty($metadata))  {                        $tool  =  new  SchemaTool($this-­‐>getEntityManager());                        $tool-­‐>dropSchema($metadata);                        $tool-­‐>createSchema($metadata);                }        }

Page 27: Behat в PHP с использованием Behat и Mink

TableNode

• getRows

• getHash

• getRowsHash

• getRowLines

• getRowAsString

• getNumeratedRows

Page 28: Behat в PHP с использованием Behat и Mink

Scenario: Given the following people exist: | name | email | phone | | Aslak | [email protected] | 123 | | Joe | [email protected] | 234 | | Bryan | [email protected] | 456 |

/** * @Given /the following people exist:/ */public function thePeopleExist(TableNode $table){    $hash = $table->getHash();    foreach ($hash as $row) {        // $row['name'], $row['email'], $row['phone']    }}

Page 29: Behat в PHP с использованием Behat и Mink

PyStringNode

• Опеределение длинного теста в несколько строчек

Page 30: Behat в PHP с использованием Behat и Mink

Scenario: Given a blog post named "Random" with: """ Some Title, Eh? =============== Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet, consectetur adipiscing elit. """

/** * @Given /a blog post named "([^"]+)" with:/ */public function blogPost($title, PyStringNode $markdown){    $this->createPost($title, $markdown->getRaw());}

Page 31: Behat в PHP с использованием Behat и Mink

Backgrounds

• Общие шаги для всех сценариев• Позволяется избавиться от дублирования шагов в каждом сценарии

Page 32: Behat в PHP с использованием Behat и Mink

   Background:        Given  the  site  has  following  users:        |  name            |        |  knplabs      |        |  fos              |        Given  the  site  has  following  bundles:        |  username    |  name              |  description  |  lastCommitAt  |  score  |  trend1  |        |  knplabs      |  TestBundle  |  test  desc      |-­‐1  day                |  10        |  15          |        |  fos              |  UserBundle  |  user  desc      |-­‐2  days              |  20        |  5            |

Page 33: Behat в PHP с использованием Behat и Mink

MetaSteps

• Объединяем несколько шагов в один

• Помогает избавиться от дублирования шагов

• Тесты запускаются по цепочке

• Возвращаем массив состоящий из шагов, которые необходимо выполнить

Page 34: Behat в PHP с использованием Behat и Mink

/** * @Given /I entered "([^"]*)" and expect "([^"]*)"/ */public function complexStep($number, $result){    return array(        new Step\Given("I have entered \"$number\""),        new Step\When("I press +"),        new Step\Then("I should see \"$result\" on the screen")    );}

Page 35: Behat в PHP с использованием Behat и Mink

ScenarioOutlines

• Помогает избавиться от дублирования сценариев

• Предоставляет удобный интерфейс для описания набора тестов и ожидаемых результатов

Page 36: Behat в PHP с использованием Behat и Mink

Scenario Outline: Given I have entered <number1> And I have entered <number2> When I add Then The result should be <result> Examples: | number1 | number2 | result | | 10 | 12 | 22 | | 5 | 3 | 8 | | 5 | 5 | 10 |

Page 37: Behat в PHP с использованием Behat и Mink

Tags

• Тэги в сценариях• Тэги в хуках• behat --tags "@orm,@database"

• behat --tags "@orm&&@database"

• beaht --tags "-@database"

Page 38: Behat в PHP с использованием Behat и Mink

Запуск сценариев

• behat features/

• behat features/single.feature

• behat features/single.feature:10-20

• behat --name=”Feature name”

• behat --tags @tag1,@tag2

• behat --profile test

Page 39: Behat в PHP с использованием Behat и Mink
Page 40: Behat в PHP с использованием Behat и Mink

Profiles

• Настройки форматтеров• Настройка контекстов• Настройки тэгов• Настройки экстеншенов• Настройка путей к файлам

Page 41: Behat в PHP с использованием Behat и Mink

# behat.ymldefault:    context:        class: Your\Custom\Contextwip:    filters:        tags: "@wip"    formatter:        name: progressci:    formatter:        name: junit        parameters:            output_path: /var/tmp/junit

Page 42: Behat в PHP с использованием Behat и Mink

Система экстеншенов

• Mink Extension

• Symfony2 Extension

• Behatch Extension

• Doctrine DataFixtures Extension

• Gearman Extension

• Write your own

Page 43: Behat в PHP с использованием Behat и Mink

Mink

Page 44: Behat в PHP с использованием Behat и Mink

Зачем?

• Слой абстракции для использования различных эмуляторов браузера

• Приемочное тестирование web-приложений

Page 45: Behat в PHP с использованием Behat и Mink

Установка

• PHP 5.3

• Composer

• PHAR

• Git

Page 46: Behat в PHP с использованием Behat и Mink

Drivers

• Goutte

• Zombie

• Selenium

• Selenium2

• Sahi

Page 47: Behat в PHP с использованием Behat и Mink

Session

• Через сессию можно получить доступ к остальным объектам: страница, статус код, куки, заголовки и т. д.

• Несколько сессий запущенных одновременно

Page 48: Behat в PHP с использованием Behat и Mink

Selectors

• Named

• CSS

• XPath

• find*

• Traversing

Page 49: Behat в PHP с использованием Behat и Mink

NodeElement

• Можем манипулировать элементом найденным по одному из селекторов

• Посмотреть аттрибуты, текст

• Эмулировать события браузера• Манипулировать элеметами формы, ввести текст в инпут, выбрать чекбокс, прикрепить файл и т. д.

Page 50: Behat в PHP с использованием Behat и Mink

Mink + Behat

• Mink Extension for Behat

• Mink может быть использован отдельно от Behat

• Минимум конфигурации

Page 51: Behat в PHP с использованием Behat и Mink

BDD workflow

Page 52: Behat в PHP с использованием Behat и Mink

• Обсуждение функционала

• Составление User stories

• Подготовка сценариев на Gherkin DSL

• Пишем недостающие Step definitions

• Пишем функционал, юнит тесты, и т. д.

• Проверяем DoD

Page 53: Behat в PHP с использованием Behat и Mink

Спасибо за внимание!