Behaviour-Driven Development is about implementing an application by describing its behavior from the perspective of its stakeholders.http://en.wikipedia.org/wiki/Behavior_Driven_Development
# A comment here Feature: Some terse yet descriptive text of what is desired In order to realize a named business value As a explicit system actor I want to gain some beneficial outcome which furthers the goal @secretlabel Scenario: Some determinable business situation Given some precondition And some other precondition When some action by the actor And some other action And yet another action Then some testable outcome is achieved And something else we can check happens too
Keywords: i18n.yml
"en": name: English native: English feature: Feature background: Background scenario: Scenario scenario_outline: Scenario Outline|Scenario Template examples: Examples|Scenarios given: "*|Given" when: "*|When" then: "*|Then" and: "*|And" but: "*|But"https://github.com/aslakhellesoy/gherkin/blob/master/lib/gherkin/i18n.yml
"en-lol": name: LOLCAT native: LOLCAT feature: OH HAI background: B4 scenario: MISHUN scenario_outline: MISHUN SRSLY examples: EXAMPLZ given: "*|I CAN HAZ" when: "*|WEN" then: "*|DEN" and: "*|AN" but: "*|BUT"https://github.com/aslakhellesoy/gherkin/blob/master/lib/gherkin/i18n.yml
OH HAI: STUFFING MISHUN: CUCUMBR I CAN HAZ IN TEH BEGINNIN 3 CUCUMBRZ WEN I EAT 2 CUCUMBRZ DEN I HAS 2 CUCUMBERZ IN MAH BELLY AN IN TEH END 1 CUCUMBRZ KTHXBAI
# Example feature Feature: To show how to run cucumber features Scenario: Simplest scenario When I go to the homepage Then I should see "Welcome to Rails"
cucumber features/myfeature.feature cucumber features cucumber features/myfeature.feature:3
# Example feature Feature: To show how to run cucumber features Scenario: Simplest scenario # features/example.feature:3 Given I am on the homepage # features/step_definitions/steps.rb:1 TODO (Cucumber::Pending) ./features/step_definitions/steps.rb:2:in `/^I am on the homepage$/' features/example.feature:4:in `Given I am on the homepage' 1 scenario (1 pending) 1 step (1 pending) 0m0.002s
ruby script/generate cucumber --rspec --capybara
# Gemfile group :test do gem 'cucumber-rails' gem 'capybara' gem 'database_cleaner' end
rails generate cucumber:install
create config/cucumber.yml create script/cucumber create features/step_definitions/web_steps.rb create features/support create features/support/paths.rb create features/support/env.rb create lib/tasks/cucumber.rake gsub config/database.ymlhttps://github.com/aslakhellesoy/cucumber-rails
<% rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : "" rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}" std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip" %> default: <%= std_opts %> features wip: --tags @wip:3 --wip features rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wiphttps://github.com/aslakhellesoy/cucumber/wiki/cucumber.yml
module NavigationHelpers def path_to(page_name) case page_name when /the home\s?page/ '/' else begin page_name =~ /the (.*) page/ path_components = $1.split(/\s+/) self.send(path_components.push('path').join('_').to_sym) rescue Object => e raise "Can't find mapping from \"#{page_name}\" to a path.\n" + "Now, go and add a mapping in #{__FILE__}" end end end end World(NavigationHelpers)
development: adapter: sqlite3 database: db/development.sqlite3 pool: 5 timeout: 5000 test: &test adapter: sqlite3 database: db/test.sqlite3 pool: 5 timeout: 5000 production: adapter: sqlite3 database: db/production.sqlite3 pool: 5 timeout: 5000 cucumber: <<: *test
https://github.com/jnicklas/capybara
Given I am on <page_name> when I go to <page_name> When I press <button> When I follow <link> When I fill in "<field>" with "<value>" When I fill in "<value>" for "<field>" When I select "<value>" from "<field>" When I check "<field>" When I choose "<field>" Then I should see "<text>" Then I should see /<regex>/ Then I should not see "<text>" Then I should not see /<regex>/ Then the "<field>" field should contain "<value>" Then the "<label>" checkbox should be checked Then I should be on <page_name> Then I should have the following query string <expected_pairs> Then show me the pagehttps://github.com/jnicklas/capybara
cucumber features/myfeature.feature
Using the default profile... .. 1 scenario (1 passed) 2 steps (2 passed) 0m0.192s
Factory.define :user do |user| user.email { Factory.next(:email) } user.password { "password" } user.password_confirmation { "password" } end Factory.define :author, :parent => :user do |author| author.after_create { |a| Factory(:article, :author => a) } end Factory.define :recruiter, :parent => :user do |recruiter| recruiter.is_recruiter { true } end
Given a user exists Given an author exists with an email of "author@example.com" Given the following recruiter exists: | email | phone number | employer name | | bill@example.com | 1234567890 | thoughtbot |http://robots.thoughtbot.com/post/284805810/gimme-three-steps
Scenario Outline: eating 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 |https://github.com/aslakhellesoy/cucumber/wiki/Scenario-outlines
Feature: Multiple site support As a Mephisto site owner I want to host blogs for different people In order to make gigantic piles of money Background: Given a global administrator named "Greg" And a blog named "Greg's anti-tax rants" And a customer named "Dr. Bill" And a blog named "Expensive Therapy" owned by "Dr. Bill" Scenario: Dr. Bill posts to his own blog Given I am logged in as Dr. Bill When I try to post to "Expensive Therapy" Then I should see "Your article was published." Scenario: Dr. Bill tries to post to somebody else's blog, and fails Given I am logged in as Dr. Bill When I try to post to "Greg's anti-tax rants" Then I should see "Hey! That's not your blog!" Scenario: Greg posts to a client's blog Given I am logged in as Greg When I try to post to "Expensive Therapy" Then I should see "Your article was published."https://github.com/aslakhellesoy/cucumber/wiki/Background
Before do # Do something before each scenario. end
After do |scenario| if(scenario.failed?) subject = "[Project X] #{scenario.exception.message}" send_failure_email(subject) end end
Around('@fast') do |scenario, block| Timeout.timeout(0.5) do block.call end endhttps://github.com/aslakhellesoy/cucumber/wiki/Hooks
Before('@cucumis,@sativus') do # This will only run before scenarios tagged # with @cucumis OR @sativus. end
Before('@cucumis', '@sativus') do # This will only run before scenarios tagged # with @cucumis AND @sativus. end
Before('@cucumis,@sativus', '@aqua') do # This will only run before scenarios tagged # with (@cucumis OR @sativus) AND @aqua end
my_heavy_object = HeavyObject.new my_heavy_object.do_it at_exit do my_heavy_object.undo_it end
AfterConfiguration do |config| puts "Features dwell in #{config.feature_dirs}" end
Transform /^(-?\d+)$/ do |number| number.to_i end
Then /^a user, named "([^']+)", should have (\d+) followers$/ do |name,count| # Without the transform your count object would be a string # and not a number count.should be_kind_of(Numeric) #... endhttps://github.com/aslakhellesoy/cucumber/wiki/Step-Argument-Transforms http://drnicwilliams.com/2009/04/15/cucumber-building-a-better-world-object/
class CustomWorld def a_helper ... end end World do CustomWorld.new end
module MyHelper def some_helper ... end end World MyHelperhttps://github.com/aslakhellesoy/cucumber/wiki/A-Whole-New-World
require 'cucumber/rake/task' Cucumber::Rake::Task.new(:features) do |t| t.rcov = true t.rcov_opts = %w{--rails --exclude features,spec,factories,/gems/} endhttps://github.com/aslakhellesoy/cucumber/wiki/Using-RCov-with-Cucumber-and-Rails
Feature "User creates a vurl" do Scenario "creating" do Given "I am on the home page" do executes { visit root_path } When "I submit a valid vurl" do executes do fill_in "vurl_url", :with => 'http://example.com' click_button 'Vurlify!' end Then "I should be on the vurl stats page" do current_url.should == stats_url(Vurl.last.slug) end And "I should see a success message" do response.body.should include('Vurl was successfully created') end And "my vurl was created" do Vurl.last.url.should == 'http://example.com' end end end end end
feature "Main page" do background do create_user :login => "jdoe" login_as "jdoe" end scenario "should show existing quotes" do create_quote :text => "A joke is a very serious thing", :author => "Winston Churchill" visit "/" page.should have_css(".quote", :count => 1) within(:css, ".quote") do page.should have_css(".text", :text => "A joke is a very serious thing") page.should have_css(".author", :text => "Winston Churchill") end end end