Если вы привыкли сначала писать код, а потом его тестировать, то с BDD такой подход совсем не уместен. Сила BDD в том, что он помогает вести разработку начиная со стадии оформления ТЗ. Для BDD это список свойств (фич), который уместно писать вместе с заказчиком.
Но самое главное, что по этому же списку происходит автоматическое тестирование проекта. Инструмент тестирования (в нашем случае это Cucumber) методично пройдет по вашему перечню и дотошно проверит реализацию каждой фичи.
Разработка с использованием Cucumber состоит из 3-х основных этапов.
По завершению этого цикла, когда все свойства проходят контроль cucumber-а, мы утверждаем с заказчиком новый список фич и заново проходим весь цикл. Делаем это до тех пор, пока не реализуем (добавим и проверим) все свойства.
Например, мы, как всегда, разрабатываем новый blog. Вот и запишем свойства нашего блога в файл
Конечно, не обязательно сразу выписывать все свойства, достаточно тех, которые вы намереваетесь реализовать в ближайшем этапе.
Свойство имеет одно или несколько сценариев поведения. Именно по этим сценарием и происходит тестирование. Каждый сценарий описывается тремя категориями: Условие (Given), Событие (When), Результат (Then). Если у вас несколько условий, событий или результатов, то дополнительные прописывается через And/But.
На этом этапе мы уже имеем понятный человеку и инструменту тестирования список фич. И уже сейчас можно запускать:
Cucumber подсказывает что делать дальше, какие поступки нам необходимо определить (step definition).
Копируем подсказку cucumber-а в
Теперь у нас готов и список фич и определено их поведение.
Запускаем тест:
Как видно, cucumber сообщил о том, что не знает ни о каком User. В таком случае создаем код модели User.
Опять запускаем Cucumber. На этот наз он ругается о другой ошибке — реализуем еще код дабы исправить ее и т.д. до тех пор.
Когда у cucumber пройдут все тесты — весь код будет реализован. Таким образом мы закончили 3-й этап и можно переходить к дальнейшему дизайну приложения и реализации новых фич.
Если интересно, в следующий раз расскажу и покажу как разрабатывается реальное приложение с
Материалы:
cukes.info — Сайт cucumber
nlp.od.ua/behavoir-driven-development — На русском о BDD
railscasts.com/episodes/155-beginning-with-cucumber — screencast Cucumber для начинающих
github.com/thoughtbot/clearance/tree/master — Clearance имеет отличный пример использования cucumber-а
Но самое главное, что по этому же списку происходит автоматическое тестирование проекта. Инструмент тестирования (в нашем случае это Cucumber) методично пройдет по вашему перечню и дотошно проверит реализацию каждой фичи.
Разработка с использованием Cucumber состоит из 3-х основных этапов.
- Описание фич проекта простым человеческим языком. И даже необязательно английским.
- Определение поступков (step definition) на Ruby
- Цикл разработки: проверка фич кукумбером и реализация не прошедших тестирование фич ручками.
По завершению этого цикла, когда все свойства проходят контроль cucumber-а, мы утверждаем с заказчиком новый список фич и заново проходим весь цикл. Делаем это до тех пор, пока не реализуем (добавим и проверим) все свойства.
1-й этап. Фичи.
Список
Например, мы, как всегда, разрабатываем новый blog. Вот и запишем свойства нашего блога в файл
./features/blog.features
. Для каждого свойства опишем также понятия Зачем, Кто и Что (In order, A, Should). Это пожелания BDD, на самом деле на результат они не влияют, но зато помогают нам самим более четко сформулировать чего-же мы хотите от этой фичи.Feature: Post articles In order to show trip photos A owner Should be abble to post article Feature: Make comments In order to contact A user Should be abble to make comments
Конечно, не обязательно сразу выписывать все свойства, достаточно тех, которые вы намереваетесь реализовать в ближайшем этапе.
Сценарии
Свойство имеет одно или несколько сценариев поведения. Именно по этим сценарием и происходит тестирование. Каждый сценарий описывается тремя категориями: Условие (Given), Событие (When), Результат (Then). Если у вас несколько условий, событий или результатов, то дополнительные прописывается через And/But.
Feature: Post articles In order to show trip photos A owner Should be abble to post article Scenario: Post article by owner Given I signed up as owner When I write article "About my last nigh trip" And text of article is "It was very hard night.." And I post article Then I should see "Article is created" Scenario: Post article by user Given I signed up as user When I write article "My fantazy" And text of article is "..no more" And I post article Then I should see "You have no access to post articles"
На этом этапе мы уже имеем понятный человеку и инструменту тестирования список фич. И уже сейчас можно запускать:
> cucumber features/blog.features ... 2 scenarios (2 undefined) 12 steps (12 undefined) 0m0.012s You can implement step definitions for undefined steps with these snippets: Given /^I signed up as owner$/ do pending end When /^I write article "([^\"]*)"$/ do |arg1| pending end When /^text of article is "([^\"]*)"$/ do |arg1| pending end When /^I post article$/ do pending end Then /^I should see "([^\"]*)"$/ do |arg1| pending end
Cucumber подсказывает что делать дальше, какие поступки нам необходимо определить (step definition).
Этап 2. Определение поступков (step definition)
Копируем подсказку cucumber-а в
/features/step_definitions/blog_steps.rb
и прописываем поступки, например:Given /^I signed up as (.*)$/ do |role| current_user=User.find_by_role(role) end When /^I write article "([^\"]*)"$/ do |arg1| aricle=Article.create(:subject=>arg1,:user=>user) same_subject=subject end When /^text of article is "([^\"]*)"$/ do |arg1| aricle.text=arg1 end When /^I post article$/ do artricle.save! end Then /^I should see "([^\"]*)"$/ do |arg1| response.should contain(arg1) end
Теперь у нас готов и список фич и определено их поведение.
Этап 3. Тестирование и разработка
Запускаем тест:
> cucumber features/blog.features Feature: Post articles In order to show trip photos A owner Should be abble to post article Scenario: Post article by owner # features/blog.features:6 Given I signed up as owner # features/step_definitions/blog_steps.rb:1 uninitialized constant User (NameError) features/blog.features:7:in `Given I signed up as owner' When I write article "About my last nigh trip" # features/step_de
Как видно, cucumber сообщил о том, что не знает ни о каком User. В таком случае создаем код модели User.
Опять запускаем Cucumber. На этот наз он ругается о другой ошибке — реализуем еще код дабы исправить ее и т.д. до тех пор.
Когда у cucumber пройдут все тесты — весь код будет реализован. Таким образом мы закончили 3-й этап и можно переходить к дальнейшему дизайну приложения и реализации новых фич.
Если интересно, в следующий раз расскажу и покажу как разрабатывается реальное приложение с
Cucumber, Shoulda
и волшебником webrat
.PS
Материалы:
cukes.info — Сайт cucumber
nlp.od.ua/behavoir-driven-development — На русском о BDD
railscasts.com/episodes/155-beginning-with-cucumber — screencast Cucumber для начинающих
github.com/thoughtbot/clearance/tree/master — Clearance имеет отличный пример использования cucumber-а