Пользователь
0,0
рейтинг
29 июня 2009 в 10:26

Разработка → BDD с помощью Cucumber

Ruby*
Если вы привыкли сначала писать код, а потом его тестировать, то с BDD такой подход совсем не уместен. Сила BDD в том, что он помогает вести разработку начиная со стадии оформления ТЗ. Для BDD это список свойств (фич), который уместно писать вместе с заказчиком.

Но самое главное, что по этому же списку происходит автоматическое тестирование проекта. Инструмент тестирования (в нашем случае это Cucumber) методично пройдет по вашему перечню и дотошно проверит реализацию каждой фичи.

Разработка с использованием Cucumber состоит из 3-х основных этапов.
  1. Описание фич проекта простым человеческим языком. И даже необязательно английским.
  2. Определение поступков (step definition) на Ruby
  3. Цикл разработки: проверка фич кукумбером и реализация не прошедших тестирование фич ручками.


По завершению этого цикла, когда все свойства проходят контроль 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-а
Данил Письменный @dapi
карма
57,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (21)

  • 0
    Спасибо за статью! Лучики вам счастья!
  • +2
    А почему не на русском, cucumber прекрасно с ним работает, вот пример:

    Функционал: Сложение чисел
    Чтобы не складывать в уме
    Все, у кого с этим туго
    Хотят автоматическое сложение целых чисел
    Сценарий: Сложение двух целых чисел
    Допустим я ввожу число 50
    И затем ввожу число 70
    Если я нажимаю "+"
    То результатом должно быть число 120

    Вот еще немного примеров

    Не знаю как вам, а мне очень нравится :)
    • 0
      Круто, самое то для заказчика!
      • 0
        Заставить заказчика писать тесты — это нереально круто. Может со временем научится make them pass :)
        • 0
          Не за него, а вместе с ним :)
    • 0
      Не знаю как вам, а мне очень нравится :)

      Тут вопрос даже не в том — нравится или нет. А в том — на каком языке вся остальная документация по проекту. Вообще важно писать сценарии приемочного тестирования на том же языке, что и вся остальная документация, так как таким образом не происходит расхождения в терминологии. Терминологические войны в проекте — та еще головная боль.
  • 0
    Интересная вещь.
    Есть аналоги для других языков?
    • 0
      Да, причем файл настроек не большой.

      С русским есть только одна проблема — интеграция со свойствами других проектов (плагинов и модулей) коих в своем великое множество — получается каша. Ну и еще по умолчанию некоторыми пакетами многие поступки уже прописываются на английском.
    • 0
      Если вы о языках програмирования, то Cucumber умеет работать с Java (Jruby).

      Так же ближайшим временем выйдет аналог под python, дайте только допилю до нормального состояния:).
      • 0
        > Так же ближайшим временем выйдет аналог под python, дайте только допилю до нормального состояния:).
        Очень ждем :)
        Работа с ним будет такой же легкочитаемой? :)
        • 0
          Да, синтаксис feature-файлов копируем от Cucumber. В текущей реализации будет даже менее строго.
    • 0
      Есть аналоги для других языков?

      Behave for Python
  • –4
    Я подумал, что речь о Binary decision diagrams пойдёт :)
    • 0
      Интересно, расскажи где они применяются и с чем едят.
      • 0
        Основная идея — использование преимуществ табличного подхода, не спотыкаясь о его недостатки. Т.е. повышение скорости (которая теперь линейно зависит от количества переменных) вычисления функции при небольшом размере структуры данных.

        Применяться могут везде, где нам необходимо быстро получить результат для небыстрой функции с небольшой областью применения (для примеров из википедии, состоящей из 2 элементов, а по сути вспомним, что у нас везде биты — мы ведь можем выразить функцию как набор булевых функций, например). Также BDD обладают свойством уникальности — для данной функции при данном порядке переменных существует единственный ROBDD. Поэтому может применяться для формальной верификации, проверки на эквивалентность.

        Мне в этой структуре нравятся три вещи

        1. Идея реализовать булеву функцию в виде графа, ускоряя вычисления.
        2. Возможность производить вычисления не распаковывая BDD.
        3. Уникальность.

        И не нравится, что нахождение оптимального порядка переменных — NP полная задача (O(N!) кажется).

        К сожалению, это оффтопик, поэтому здесь остановлюсь.

        И спасибо за статью!
  • 0
    Очень интересно! Продолжайте пожалуйста!
  • +1
    в целом весьма неплохо, но:

    я, конечно, не гуру бдд, но перевод «step definition» как «описание поступков» сомнителен. я бы перевел как «описание шагов» либо «реализация шагов».

    еще. пример не очень удачен. по крайней мере в том виде в котором он есть — работать не будет. по многим причинам. начиная с того, что article — локальная переменная, заканчивая тем, что контроллер не дергается, а соответственно response будет nil. и вообще, описание шага Then I should see «something» идет вместе в webrat'ом.

    и еще. если уж речь идет о конкретном инструменте, неплохо для начала дать описание как настроить environment с cucumber'ом (хоть под рельсами, хоть без них), дать описание структуры директорий.

    да, я зануда. извините.
    • 0
      Вы правы.

      Дело в том, что цель статьи ознакомить с методикой и только. Хотя приведенные выше тесты в рамках cucumber-а рабочие — проверено. Что касается нюансов реализации поступков, то они описаны так умышленно, для упрощения понимания, опять таки работы самого cucumber-а.

      Насчет «шагов» и «поступков» вы также правы. Но мне больше нравится слово «поступки», так как «шаги» часто употребляется с иными контекстом и может ввести в заблуждение. Слово шаги также подразумевает некоторую этапность, которая в случае с (step definition) отсутствует.

      Насчет environment — как уже говорил, приведенные настройки кукумбера работают и так, остальное уже выходит за рамки данной статьи.

      Согласен, нужно освятить этот вопрос более подробно, но для этого необходимо также ввести публику и shoulda, и в webrat, также желательно ознакомить factory_girl и mocha, иначе не будет понятно где мы говорим о BDD и огурце, а где применяем другие инструменты.

      Предлагаю разделиться и написать нам статьи по этим темам. А в конце заключительную статью, в которой полностью рассмотрим разработку реального приложения с помощью этих инструментов.

      Что выбираете?
  • 0
    Отличная тематика, если у вас есть, что рассказать, продолжайте, не останавливайтесь на этом!
  • 0
    Все конечно замечательно, спасибо и все такое, но… чем эта статья отличается от тупо перевода скринкаста, указанного в конце статьи? Там еще и подробнее все описано, и понятнее, и… работает!
  • 0
    Для BDD это список свойств (фич), который уместно писать вместе с заказчиком.

    Уже набило оскомину утверждение, с заказчиком можно/нужно писать сценарии на Gherkin-е. С заказчиком нельзя написать полноценные сценарии тестирования. Заказчик — это такой зверь, которому нужно подавать решение его проблемы в самом вкусном и удобовоспринимаемом виде. Иначе не будет переварено.

    Да даже, если речь идет о том, что вы при заказчике пишете сценарии, сами конвертируя в них его требования, то это не будет оценено по достоинству. Заказчику нужна картинка.

    Это может быть, например, презентация с набором диаграмм (например user story и job story), но никак не техническая спецификация, коей является Gherkin.

    Единственный случай когда с заказчиком можно разрабатывать требования к продукту на Gherkin-е — это когда заказчиком является технарь, либо какой-то отдел вашей же компании (то есть в любом случае технарь).

    В других же случаях Gherkin при работе с заказчиком пригодится лишь на этапе утверждения объема работы на разработку. Мол мы вам привели в формально изложенном виде то что будет нами сделано, вы утвердили, мы разрабатываем. И делать это нужно только когда все это было уже изложено в более удобоваримом виде.

    В общем, хватит людей в заблуждение вводить. Тут явно должны быть какие то другие формулировки. (Никаких претензий к переводчику, так как в общем статья полезная)

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