SlideShare uma empresa Scribd logo
1 de 53
Baixar para ler offline
BDD в PHP
с использованием
   Behat и Mink
About me

•   Symfony developer at
    KnpLabs

•   twitter: @tyomo4ka

•   GitHub: tyomo4ka
Happy Awesome Developers
Agenda

• BDD
• Gherkin DSL
• Behat
• Mink
• BDD workflow
Зачем тестировать?

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

• TDD не очень удачое название
• Если мы пишем тесты перед кодом, мы
  все равно думаем об архитектуре
• Design Driven Development?
TDD и BDD
• Также пишем тесты перед кодом
• При TDD мы фиксируем в тестах
  архитектуру приложения или его частей
• При BDD мы фиксируем в тестах
  поведение приложения или его частей
• Описательная часть: спецификация или
  пользовательские сценарии
Spec BDD
• Добавляем описательную часть к тестам
• Получаем не тесты, а спецификации
  объектов
• Тестирование системы изнутри
• Используем вместо юнит тестов и
  интеграционых тестов
Story (Scenario) BDD
• Вместо тестов описываем шаги, которые
  нужно выполнить для достижения
  определнного результата
• Шаги должны легко читаться, в идеале
  это должны быть простые предложения
• Тестирование системы снаружи
• Замена функциональным тестам
Gherkin DSL
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 |
            | active@user.com | password | no       |
            | blocked@user.com | password | yes     |

    Scenario: Successful login
        Given I am on page "Login"
        When I fill in "Username" with "active@user.com"
        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"
Feature: Название функционала
    In order to ... Ценность функционала
    As a ... Выгодополучатель
    I need ... Краткое описание функционала

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

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


•   A php framework for testing your
    business expectations
Установка

• PHP 5.3
• Composer
• PHAR
• Git
Инициализация

• behat --init
• features/ directory
• features/bootstrap/ directory
• features/bootstrap/*Context.php
• behat.yml
features/*.feature


• Gherkin DSL
• behat --story-syntax --lang=LANG
[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      |
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
Context

• POPO
• Описание шагов
• Хуки
• Subcontexts
• Closures для описания шагов и хуков
 	
  	
  	
  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());
	
  	
  	
  	
  }
Steps definition

• @Given, @When, @Then
• Если шаг не выбросил исключение,
  значит он завершился успешно
• Нет своих асершенов, но легко можно
  использовать асершены из PHPUnit
 	
  	
  	
  /**
	
  	
  	
  	
  	
  *	
  @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('KnpBundleKnpBundlesBundleEntityKeyword')
                                                -­‐>findOrCreateOne($row['keyword']);
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  $bundle-­‐>addKeyword($keyword);
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  $entityManager-­‐>persist($bundle);
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }
	
  	
  	
  	
  	
  	
  	
  	
  }

	
  	
  	
  	
  	
  	
  	
  	
  $entityManager-­‐>flush();
	
  	
  	
  	
  }
Hooks

• BeforeStep/AfterStep
• BeforeScenario/AfterScenario
• BeforeFeature/AfterFeature
• BeforeSuite/AfterSuite
• Hooks can be tagged
 	
  	
  	
  /**
	
  	
  	
  	
  	
  *	
  @BeforeScenario
	
  	
  	
  	
  	
  *
	
  	
  	
  	
  	
  *	
  @return	
  null
	
  	
  	
  	
  	
  */
	
  	
  	
  	
  public	
  function	
  buildSchema($event)
	
  	
  	
  	
  {
	
  	
  	
  	
  	
  	
  	
  	
  $metadata	
  =	
  $this-­‐>getMetadata();

	
  	
  	
  	
  	
  	
  	
  	
  if	
  (!empty($metadata))	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  $tool	
  =	
  new	
  SchemaTool($this-­‐>getEntityManager());
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  $tool-­‐>dropSchema($metadata);
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  $tool-­‐>createSchema($metadata);
	
  	
  	
  	
  	
  	
  	
  	
  }
	
  	
  	
  	
  }
TableNode
• getRows
• getHash
• getRowsHash
• getRowLines
• getRowAsString
• getNumeratedRows
Scenario:
  Given the   following people exist:
    | name    | email           | phone   |
    | Aslak   | aslak@email.com | 123     |
    | Joe     | joe@email.com   | 234     |
    | Bryan   | bryan@email.org | 456     |




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


• Опеределение длинного теста в
  несколько строчек
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());
}
Backgrounds


• Общие шаги для всех сценариев
• Позволяется избавиться от дублирования
  шагов в каждом сценарии
 	
  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	
  	
  	
  	
  	
  	
  |
MetaSteps
• Объединяем несколько шагов в один
• Помогает избавиться от дублирования
  шагов
• Тесты запускаются по цепочке
• Возвращаем массив состоящий из шагов,
  которые необходимо выполнить
/**
  * @Given /I entered "([^"]*)" and expect "([^"]*)"/
  */
public function complexStep($number, $result)
{
    return array(
        new StepGiven("I have entered "$number""),
        new StepWhen("I press +"),
        new StepThen("I should see "$result" on the screen")
    );
}
ScenarioOutlines

• Помогает избавиться от дублирования
  сценариев
• Предоставляет удобный интерфейс для
  описания набора тестов и ожидаемых
  результатов
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       |
Tags

• Тэги в сценариях
• Тэги в хуках
• behat --tags "@orm,@database"
• behat --tags "@orm&&@database"
• beaht --tags "-@database"
Запуск сценариев
• behat features/
• behat features/single.feature
• behat features/single.feature:10-20
• behat --name=”Feature name”
• behat --tags @tag1,@tag2
• behat --profile test
Profiles

• Настройки форматтеров
• Настройка контекстов
• Настройки тэгов
• Настройки экстеншенов
• Настройка путей к файлам
# behat.yml
default:
    context:
        class:      YourCustomContext
wip:
    filters:
        tags:       "@wip"
    formatter:
        name:       progress
ci:
    formatter:
        name:       junit
        parameters:
            output_path: /var/tmp/junit
Система экстеншенов
• Mink Extension
• Symfony2 Extension
• Behatch Extension
• Doctrine DataFixtures   Extension
• Gearman Extension
• Write your own
Mink
Зачем?

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

• PHP 5.3
• Composer
• PHAR
• Git
Drivers

• Goutte
• Zombie
• Selenium
• Selenium2
• Sahi
Session

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

• Named
• CSS
• XPath
• find*
• Traversing
NodeElement
• Можем манипулировать элементом
  найденным по одному из селекторов
• Посмотреть аттрибуты, текст
• Эмулировать события браузера
• Манипулировать элеметами формы,
  ввести текст в инпут, выбрать чекбокс,
  прикрепить файл и т. д.
Mink + Behat

• Mink Extension for Behat
• Mink может быть использован отдельно
  от Behat
• Минимум конфигурации
BDD workflow
• Обсуждение функционала
• Составление User stories
• Подготовка сценариев на Gherkin DSL
• Пишем недостающие Step definitions
• Пишем функционал, юнит тесты, и т. д.
• Проверяем DoD
Спасибо за внимание!

Mais conteúdo relacionado

Mais procurados

Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорьdrupalconf
 
Автоматизация UI тестирования под Windows и Windows Phone
Автоматизация UI тестирования под Windows и Windows PhoneАвтоматизация UI тестирования под Windows и Windows Phone
Автоматизация UI тестирования под Windows и Windows PhoneCodeFest
 
Saint Perl 2009: CGI::Ajax demo
Saint Perl 2009: CGI::Ajax demoSaint Perl 2009: CGI::Ajax demo
Saint Perl 2009: CGI::Ajax demomegakott
 
2014 Jeeconf - Geb Spock
2014 Jeeconf - Geb Spock2014 Jeeconf - Geb Spock
2014 Jeeconf - Geb SpockBohdan Danyliuk
 
Angular 2: Всех переиграл
Angular 2: Всех переигралAngular 2: Всех переиграл
Angular 2: Всех переигралEugene Zharkov
 
М. Боднарчук Современное функциональное тестирование с Codeception
М. Боднарчук Современное функциональное тестирование с CodeceptionМ. Боднарчук Современное функциональное тестирование с Codeception
М. Боднарчук Современное функциональное тестирование с CodeceptionAlbina Tiupa
 
Everything You Need to Know About WP_Query, WordCamp Russia 2014
Everything You Need to Know About WP_Query, WordCamp Russia 2014Everything You Need to Know About WP_Query, WordCamp Russia 2014
Everything You Need to Know About WP_Query, WordCamp Russia 2014Sergey Biryukov
 
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)Ontico
 
CodeFest 2012. Родионов А. — Тестирование Ruby (on Rails) приложений: стек, п...
CodeFest 2012. Родионов А. — Тестирование Ruby (on Rails) приложений: стек, п...CodeFest 2012. Родионов А. — Тестирование Ruby (on Rails) приложений: стек, п...
CodeFest 2012. Родионов А. — Тестирование Ruby (on Rails) приложений: стек, п...CodeFest
 
Михаил Боднарчук Современное функциональное тестирование с Codeception
Михаил Боднарчук Современное функциональное тестирование с CodeceptionМихаил Боднарчук Современное функциональное тестирование с Codeception
Михаил Боднарчук Современное функциональное тестирование с CodeceptionAlbina Tiupa
 
i18n for Plugin and Theme Developers, WordCamp Moscow 2016
i18n for Plugin and Theme Developers, WordCamp Moscow 2016i18n for Plugin and Theme Developers, WordCamp Moscow 2016
i18n for Plugin and Theme Developers, WordCamp Moscow 2016Sergey Biryukov
 
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
Системное тестирование  приложений на Ruby on Rails с применением Rspec и Cap...Системное тестирование  приложений на Ruby on Rails с применением Rspec и Cap...
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...lshevtsov
 
JS Fest 2018. Лилия Карпенко. Особенности создания IOS / Android Mobile Apps ...
JS Fest 2018. Лилия Карпенко. Особенности создания IOS / Android Mobile Apps ...JS Fest 2018. Лилия Карпенко. Особенности создания IOS / Android Mobile Apps ...
JS Fest 2018. Лилия Карпенко. Особенности создания IOS / Android Mobile Apps ...JSFestUA
 
Alexander manuhin selenium_php_v2.0
Alexander manuhin selenium_php_v2.0Alexander manuhin selenium_php_v2.0
Alexander manuhin selenium_php_v2.0matroskin1980
 
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полнойОмские ИТ-субботники
 
Микрофреймворки PHP
Микрофреймворки PHPМикрофреймворки PHP
Микрофреймворки PHPEkaterina Giganova
 
"VUE.JS как реакт с человеческим лицом" Дулецкий Вольдэмар, Evrone
"VUE.JS как реакт с человеческим лицом" Дулецкий Вольдэмар, Evrone"VUE.JS как реакт с человеческим лицом" Дулецкий Вольдэмар, Evrone
"VUE.JS как реакт с человеческим лицом" Дулецкий Вольдэмар, Evroneit-people
 
Selenium: начало работы
Selenium: начало работыSelenium: начало работы
Selenium: начало работыPaul Stashevsky
 
"Жизнь без интернета" Кувалдин Артём, Яндекс
"Жизнь без интернета" Кувалдин Артём, Яндекс"Жизнь без интернета" Кувалдин Артём, Яндекс
"Жизнь без интернета" Кувалдин Артём, Яндексit-people
 

Mais procurados (20)

Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорь
 
Автоматизация UI тестирования под Windows и Windows Phone
Автоматизация UI тестирования под Windows и Windows PhoneАвтоматизация UI тестирования под Windows и Windows Phone
Автоматизация UI тестирования под Windows и Windows Phone
 
Saint Perl 2009: CGI::Ajax demo
Saint Perl 2009: CGI::Ajax demoSaint Perl 2009: CGI::Ajax demo
Saint Perl 2009: CGI::Ajax demo
 
2014 Jeeconf - Geb Spock
2014 Jeeconf - Geb Spock2014 Jeeconf - Geb Spock
2014 Jeeconf - Geb Spock
 
Angular 2: Всех переиграл
Angular 2: Всех переигралAngular 2: Всех переиграл
Angular 2: Всех переиграл
 
М. Боднарчук Современное функциональное тестирование с Codeception
М. Боднарчук Современное функциональное тестирование с CodeceptionМ. Боднарчук Современное функциональное тестирование с Codeception
М. Боднарчук Современное функциональное тестирование с Codeception
 
Everything You Need to Know About WP_Query, WordCamp Russia 2014
Everything You Need to Know About WP_Query, WordCamp Russia 2014Everything You Need to Know About WP_Query, WordCamp Russia 2014
Everything You Need to Know About WP_Query, WordCamp Russia 2014
 
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
TypeScript: особенности разработки / Александр Майоров (Tutu.ru)
 
CodeFest 2012. Родионов А. — Тестирование Ruby (on Rails) приложений: стек, п...
CodeFest 2012. Родионов А. — Тестирование Ruby (on Rails) приложений: стек, п...CodeFest 2012. Родионов А. — Тестирование Ruby (on Rails) приложений: стек, п...
CodeFest 2012. Родионов А. — Тестирование Ruby (on Rails) приложений: стек, п...
 
Основы доменной модели
Основы доменной моделиОсновы доменной модели
Основы доменной модели
 
Михаил Боднарчук Современное функциональное тестирование с Codeception
Михаил Боднарчук Современное функциональное тестирование с CodeceptionМихаил Боднарчук Современное функциональное тестирование с Codeception
Михаил Боднарчук Современное функциональное тестирование с Codeception
 
i18n for Plugin and Theme Developers, WordCamp Moscow 2016
i18n for Plugin and Theme Developers, WordCamp Moscow 2016i18n for Plugin and Theme Developers, WordCamp Moscow 2016
i18n for Plugin and Theme Developers, WordCamp Moscow 2016
 
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
Системное тестирование  приложений на Ruby on Rails с применением Rspec и Cap...Системное тестирование  приложений на Ruby on Rails с применением Rspec и Cap...
Системное тестирование приложений на Ruby on Rails с применением Rspec и Cap...
 
JS Fest 2018. Лилия Карпенко. Особенности создания IOS / Android Mobile Apps ...
JS Fest 2018. Лилия Карпенко. Особенности создания IOS / Android Mobile Apps ...JS Fest 2018. Лилия Карпенко. Особенности создания IOS / Android Mobile Apps ...
JS Fest 2018. Лилия Карпенко. Особенности создания IOS / Android Mobile Apps ...
 
Alexander manuhin selenium_php_v2.0
Alexander manuhin selenium_php_v2.0Alexander manuhin selenium_php_v2.0
Alexander manuhin selenium_php_v2.0
 
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
 
Микрофреймворки PHP
Микрофреймворки PHPМикрофреймворки PHP
Микрофреймворки PHP
 
"VUE.JS как реакт с человеческим лицом" Дулецкий Вольдэмар, Evrone
"VUE.JS как реакт с человеческим лицом" Дулецкий Вольдэмар, Evrone"VUE.JS как реакт с человеческим лицом" Дулецкий Вольдэмар, Evrone
"VUE.JS как реакт с человеческим лицом" Дулецкий Вольдэмар, Evrone
 
Selenium: начало работы
Selenium: начало работыSelenium: начало работы
Selenium: начало работы
 
"Жизнь без интернета" Кувалдин Артём, Яндекс
"Жизнь без интернета" Кувалдин Артём, Яндекс"Жизнь без интернета" Кувалдин Артём, Яндекс
"Жизнь без интернета" Кувалдин Артём, Яндекс
 

Destaque

Behat dpc12
Behat dpc12Behat dpc12
Behat dpc12benwaine
 
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)SQALab
 
Qa Automation - отбрасываем лишнее и тестируем суть
Qa Automation - отбрасываем лишнее и тестируем сутьQa Automation - отбрасываем лишнее и тестируем суть
Qa Automation - отбрасываем лишнее и тестируем сутьIgor Khrol
 
Типичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriverТипичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriverIgor Khrol
 
Провокации автоматического тестирования
Провокации автоматического тестированияПровокации автоматического тестирования
Провокации автоматического тестированияSQALab
 
Автоматизация тестирования WEB API
Автоматизация тестирования WEB APIАвтоматизация тестирования WEB API
Автоматизация тестирования WEB APISQALab
 
Когда стоит закончить автоматизировать?
Когда стоит закончить автоматизировать?Когда стоит закончить автоматизировать?
Когда стоит закончить автоматизировать?SQALab
 
Introduction to Selenium and Ruby
Introduction to Selenium and RubyIntroduction to Selenium and Ruby
Introduction to Selenium and RubyYnon Perek
 

Destaque (10)

BDD в PHP с Behat и Mink
BDD в PHP с Behat и MinkBDD в PHP с Behat и Mink
BDD в PHP с Behat и Mink
 
Behat dpc12
Behat dpc12Behat dpc12
Behat dpc12
 
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
 
Qa Automation - отбрасываем лишнее и тестируем суть
Qa Automation - отбрасываем лишнее и тестируем сутьQa Automation - отбрасываем лишнее и тестируем суть
Qa Automation - отбрасываем лишнее и тестируем суть
 
Типичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriverТипичные ошибки начинающих писать тесты на WebDriver
Типичные ошибки начинающих писать тесты на WebDriver
 
Провокации автоматического тестирования
Провокации автоматического тестированияПровокации автоматического тестирования
Провокации автоматического тестирования
 
Автоматизация тестирования WEB API
Автоматизация тестирования WEB APIАвтоматизация тестирования WEB API
Автоматизация тестирования WEB API
 
The Dangers of Cucumber
The Dangers of CucumberThe Dangers of Cucumber
The Dangers of Cucumber
 
Когда стоит закончить автоматизировать?
Когда стоит закончить автоматизировать?Когда стоит закончить автоматизировать?
Когда стоит закончить автоматизировать?
 
Introduction to Selenium and Ruby
Introduction to Selenium and RubyIntroduction to Selenium and Ruby
Introduction to Selenium and Ruby
 

Semelhante a Behat в PHP с использованием Behat и Mink

Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов ИгорьPVasili
 
Профилирование и оптимизация jQuery–кода
Профилирование и оптимизация jQuery–кодаПрофилирование и оптимизация jQuery–кода
Профилирование и оптимизация jQuery–кодаprivate_face
 
Профилирование и оптимизация jQuery–кода (Владимир Журавлёв)
Профилирование и оптимизация jQuery–кода (Владимир Журавлёв)Профилирование и оптимизация jQuery–кода (Владимир Журавлёв)
Профилирование и оптимизация jQuery–кода (Владимир Журавлёв)Ontico
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПKirill Chebunin
 
Профилирования и оптимизация jQuery-кода
Профилирования и оптимизация jQuery-кодаПрофилирования и оптимизация jQuery-кода
Профилирования и оптимизация jQuery-кодаprivate_face
 
Регрессионное тестирование верстки
Регрессионное тестирование версткиРегрессионное тестирование верстки
Регрессионное тестирование версткиTalks&Works
 
View как чистая функция от состояния базы данных - Илья Беда, bro.agency
View как чистая функция от состояния базы данных  - Илья Беда, bro.agencyView как чистая функция от состояния базы данных  - Илья Беда, bro.agency
View как чистая функция от состояния базы данных - Илья Беда, bro.agencyit-people
 
Фундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоФундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоStanfy
 
Виталий Каторгин, Wamba
Виталий Каторгин, WambaВиталий Каторгин, Wamba
Виталий Каторгин, WambaOntico
 
automation is iOS development
automation is iOS developmentautomation is iOS development
automation is iOS developmentIvan Trifonov
 
Устройство фреймворка symfony 2 (http://frontend-dev.ru)
Устройство фреймворка symfony 2 (http://frontend-dev.ru)Устройство фреймворка symfony 2 (http://frontend-dev.ru)
Устройство фреймворка symfony 2 (http://frontend-dev.ru)Александр Егурцов
 
Yii development
Yii developmentYii development
Yii developmentMageCloud
 
Psgi app
Psgi appPsgi app
Psgi appund3f
 
Ice Php Framework Preview Release
Ice Php Framework Preview ReleaseIce Php Framework Preview Release
Ice Php Framework Preview ReleaseDenis Shestakov
 

Semelhante a Behat в PHP с использованием Behat и Mink (20)

Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов Игорь
 
Почему Mojolicious?
Почему Mojolicious?Почему Mojolicious?
Почему Mojolicious?
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
Профилирование и оптимизация jQuery–кода
Профилирование и оптимизация jQuery–кодаПрофилирование и оптимизация jQuery–кода
Профилирование и оптимизация jQuery–кода
 
Профилирование и оптимизация jQuery–кода (Владимир Журавлёв)
Профилирование и оптимизация jQuery–кода (Владимир Журавлёв)Профилирование и оптимизация jQuery–кода (Владимир Журавлёв)
Профилирование и оптимизация jQuery–кода (Владимир Журавлёв)
 
PowerShell
PowerShellPowerShell
PowerShell
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОП
 
Профилирования и оптимизация jQuery-кода
Профилирования и оптимизация jQuery-кодаПрофилирования и оптимизация jQuery-кода
Профилирования и оптимизация jQuery-кода
 
Erlang tasty & useful stuff
Erlang tasty & useful stuffErlang tasty & useful stuff
Erlang tasty & useful stuff
 
UWDC 2013, Yii2
UWDC 2013, Yii2UWDC 2013, Yii2
UWDC 2013, Yii2
 
Tdd php
Tdd phpTdd php
Tdd php
 
Регрессионное тестирование верстки
Регрессионное тестирование версткиРегрессионное тестирование верстки
Регрессионное тестирование верстки
 
View как чистая функция от состояния базы данных - Илья Беда, bro.agency
View как чистая функция от состояния базы данных  - Илья Беда, bro.agencyView как чистая функция от состояния базы данных  - Илья Беда, bro.agency
View как чистая функция от состояния базы данных - Илья Беда, bro.agency
 
Фундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоФундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел Тайкало
 
Виталий Каторгин, Wamba
Виталий Каторгин, WambaВиталий Каторгин, Wamba
Виталий Каторгин, Wamba
 
automation is iOS development
automation is iOS developmentautomation is iOS development
automation is iOS development
 
Устройство фреймворка symfony 2 (http://frontend-dev.ru)
Устройство фреймворка symfony 2 (http://frontend-dev.ru)Устройство фреймворка symfony 2 (http://frontend-dev.ru)
Устройство фреймворка symfony 2 (http://frontend-dev.ru)
 
Yii development
Yii developmentYii development
Yii development
 
Psgi app
Psgi appPsgi app
Psgi app
 
Ice Php Framework Preview Release
Ice Php Framework Preview ReleaseIce Php Framework Preview Release
Ice Php Framework Preview Release
 

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

  • 1. BDD в PHP с использованием Behat и Mink
  • 2. About me • Symfony developer at KnpLabs • twitter: @tyomo4ka • GitHub: tyomo4ka
  • 4. Agenda • BDD • Gherkin DSL • Behat • Mink • BDD workflow
  • 5. Зачем тестировать? • Безопасный рефакторинг • Отсутствие регрессий • Более качеcтвенная архитектура • Уменьшение числа багов • Степень зрелости разработчика?
  • 7. TDD • TDD не очень удачое название • Если мы пишем тесты перед кодом, мы все равно думаем об архитектуре • Design Driven Development?
  • 8. TDD и BDD • Также пишем тесты перед кодом • При TDD мы фиксируем в тестах архитектуру приложения или его частей • При BDD мы фиксируем в тестах поведение приложения или его частей • Описательная часть: спецификация или пользовательские сценарии
  • 9. Spec BDD • Добавляем описательную часть к тестам • Получаем не тесты, а спецификации объектов • Тестирование системы изнутри • Используем вместо юнит тестов и интеграционых тестов
  • 10. Story (Scenario) BDD • Вместо тестов описываем шаги, которые нужно выполнить для достижения определнного результата • Шаги должны легко читаться, в идеале это должны быть простые предложения • Тестирование системы снаружи • Замена функциональным тестам
  • 12. 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 | | active@user.com | password | no | | blocked@user.com | password | yes | Scenario: Successful login Given I am on page "Login" When I fill in "Username" with "active@user.com" 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"
  • 13. Feature: Название функционала In order to ... Ценность функционала As a ... Выгодополучатель I need ... Краткое описание функционала Background: Given ... Начальное состояние системы Scenario: Название сценария Given ... Начальное состояние And ... Начальное состояние When ... Выполняем шаг And ... Выполняем шаг Then ... Проверяем результат And ... Проверяем результат
  • 14. Behat
  • 15. Зачем? • A php framework for testing your business expectations
  • 16. Установка • PHP 5.3 • Composer • PHAR • Git
  • 17. Инициализация • behat --init • features/ directory • features/bootstrap/ directory • features/bootstrap/*Context.php • behat.yml
  • 18. features/*.feature • Gherkin DSL • behat --story-syntax --lang=LANG
  • 19. [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 |
  • 20. 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
  • 21. Context • POPO • Описание шагов • Хуки • Subcontexts • Closures для описания шагов и хуков
  • 22.        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());        }
  • 23. Steps definition • @Given, @When, @Then • Если шаг не выбросил исключение, значит он завершился успешно • Нет своих асершенов, но легко можно использовать асершены из PHPUnit
  • 24.        /**          *  @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('KnpBundleKnpBundlesBundleEntityKeyword') -­‐>findOrCreateOne($row['keyword']);                                $bundle-­‐>addKeyword($keyword);                                $entityManager-­‐>persist($bundle);                        }                }                $entityManager-­‐>flush();        }
  • 25. Hooks • BeforeStep/AfterStep • BeforeScenario/AfterScenario • BeforeFeature/AfterFeature • BeforeSuite/AfterSuite • Hooks can be tagged
  • 26.        /**          *  @BeforeScenario          *          *  @return  null          */        public  function  buildSchema($event)        {                $metadata  =  $this-­‐>getMetadata();                if  (!empty($metadata))  {                        $tool  =  new  SchemaTool($this-­‐>getEntityManager());                        $tool-­‐>dropSchema($metadata);                        $tool-­‐>createSchema($metadata);                }        }
  • 27. TableNode • getRows • getHash • getRowsHash • getRowLines • getRowAsString • getNumeratedRows
  • 28. Scenario: Given the following people exist: | name | email | phone | | Aslak | aslak@email.com | 123 | | Joe | joe@email.com | 234 | | Bryan | bryan@email.org | 456 | /** * @Given /the following people exist:/ */ public function thePeopleExist(TableNode $table) {     $hash = $table->getHash();     foreach ($hash as $row) {         // $row['name'], $row['email'], $row['phone']     } }
  • 29. PyStringNode • Опеределение длинного теста в несколько строчек
  • 30. 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()); }
  • 31. Backgrounds • Общие шаги для всех сценариев • Позволяется избавиться от дублирования шагов в каждом сценарии
  • 32.    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            |
  • 33. MetaSteps • Объединяем несколько шагов в один • Помогает избавиться от дублирования шагов • Тесты запускаются по цепочке • Возвращаем массив состоящий из шагов, которые необходимо выполнить
  • 34. /** * @Given /I entered "([^"]*)" and expect "([^"]*)"/ */ public function complexStep($number, $result) {     return array(         new StepGiven("I have entered "$number""),         new StepWhen("I press +"),         new StepThen("I should see "$result" on the screen")     ); }
  • 35. ScenarioOutlines • Помогает избавиться от дублирования сценариев • Предоставляет удобный интерфейс для описания набора тестов и ожидаемых результатов
  • 36. 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 |
  • 37. Tags • Тэги в сценариях • Тэги в хуках • behat --tags "@orm,@database" • behat --tags "@orm&&@database" • beaht --tags "-@database"
  • 38. Запуск сценариев • behat features/ • behat features/single.feature • behat features/single.feature:10-20 • behat --name=”Feature name” • behat --tags @tag1,@tag2 • behat --profile test
  • 39.
  • 40. Profiles • Настройки форматтеров • Настройка контекстов • Настройки тэгов • Настройки экстеншенов • Настройка путей к файлам
  • 41. # behat.yml default:     context:         class: YourCustomContext wip:     filters:         tags: "@wip"     formatter:         name: progress ci:     formatter:         name: junit         parameters:             output_path: /var/tmp/junit
  • 42. Система экстеншенов • Mink Extension • Symfony2 Extension • Behatch Extension • Doctrine DataFixtures Extension • Gearman Extension • Write your own
  • 43. Mink
  • 44. Зачем? • Слой абстракции для использования различных эмуляторов браузера • Приемочное тестирование web- приложений
  • 45. Установка • PHP 5.3 • Composer • PHAR • Git
  • 46. Drivers • Goutte • Zombie • Selenium • Selenium2 • Sahi
  • 47. Session • Через сессию можно получить доступ к остальным объектам: страница, статус код, куки, заголовки и т. д. • Несколько сессий запущенных одновременно
  • 48. Selectors • Named • CSS • XPath • find* • Traversing
  • 49. NodeElement • Можем манипулировать элементом найденным по одному из селекторов • Посмотреть аттрибуты, текст • Эмулировать события браузера • Манипулировать элеметами формы, ввести текст в инпут, выбрать чекбокс, прикрепить файл и т. д.
  • 50. Mink + Behat • Mink Extension for Behat • Mink может быть использован отдельно от Behat • Минимум конфигурации
  • 52. • Обсуждение функционала • Составление User stories • Подготовка сценариев на Gherkin DSL • Пишем недостающие Step definitions • Пишем функционал, юнит тесты, и т. д. • Проверяем DoD