Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Behavior Driven Development

Behavior Driven Development

An introduction to behavior driven development in ruby. Introduces RSpec and Cucumber.

Guido Marucci Blas

May 27, 2013
Tweet

More Decks by Guido Marucci Blas

Other Decks in Programming

Transcript

  1. Di erent types of testing Unit testing Integration test Acceptance

    test Low Level High Level Monday, May 27, 13
  2. Unit testing Should be developer centric Should be easy to

    read Should not be fragile Should be maintainable Monday, May 27, 13
  3. Unit testing Should tests only the public interface Should assume

    preconditions and asserts post conditions Should be isolated Should not depend on external services Monday, May 27, 13
  4. Behavior Driven Development Focus on specification rather than implementation TDD

    combined with domain language Domain-Drive Design Should describe behavior It can be used as documentation Monday, May 27, 13
  5. Acceptance testing Feature centric Uses Domain Specific Language Serves as

    documentation Can be read and written by non developers It’s just English Monday, May 27, 13
  6. Cucumber Serves as documentation Feature: guess code Feature: code-breaker submits

    guess In order to determine the result of a guess As a code-breaker I want the mastermind to mark the guesses with black and the pegs with white "markers". Scenario: submit guess Given the secret code is "R G Y B" When I guess "R G B Y" Then the mark should be "BBWW" Monday, May 27, 13
  7. Cucumber Serves as documentation # Steps definition Given(/^the secret code

    is (. . . .)$/) do |code| @messenger = StringIO.new @game ||= Mastermind::Game.new(messenger) game.start(code) end When(/^I guess (. . . .)$/) do |guess| @game.guess(guess) end Then(/^the mark should be (.*)$/) do |mark| @messenger.string.split("\n").should include(message) end Monday, May 27, 13
  8. Capybara DSL library to interact with web UI Plays nicely

    with Ruby testing frameworks Can define which driver uses Monday, May 27, 13
  9. Capybara visit users_path fill_in "Email", with: @user.email fill_in "Password", with:

    @user.password click_button "Sign in" click_link "Save" save_and_open_page page.should have_content "some text" Monday, May 27, 13
  10. Cucumber & Capybara Feature: Create task In order keep track

    of the tasks I have to do As a user I want to be able to create new tasks Scenario: Create task Given I have signed in When I go to the task form And create a new task Then the above task should be created Monday, May 27, 13
  11. Cucumber & Capybara Given(/^I have signed in$/) do user =

    User.create(email: "[email protected]", password: "password") visit(new_user_session_path) fill_in("Email", :with => @user.email) fill_in("Password", :with => @user.password) click_button("Sign in") end When(/^I go to the task form$/) do visit(tasks_path) end When(/^create a new task$/) do fill_in('Description', :with => 'Find the meaning of life') click_button('Create Task') end Then(/^the above (.*) should be created$/) do |model| model.humanize.constantize.count().should == 1 // Task.count().should == 1 end Then(/^I should see the text "(.*)"$/) do |text| page.should have_content(text) end Monday, May 27, 13
  12. Cucumber & Capybara Feature: Create task In order keep track

    of the tasks I have to do As a user I want to be able to create new tasks Scenario: Create task Given the User with email "[email protected]" and password "123456" exists And I visit the login page And I fill email with "[email protected]" And I fill password with "123456" And I click the submit button And I visit the new task page And I fill name with "My Task" And I fill description with "A cool description" And I click the create button Then I should be in the task page And I should see the text "My Task" And I should see the text "A cool description" Monday, May 27, 13
  13. Tips • Use “Then show me the page” (show_me_the_page) •

    Use “Then debug” (breakpoint) • Group steps in different files • Organize features in subdirectories • Use backgrounds • Invoke steps within steps Monday, May 27, 13
  14. Best Practices Use domain language to write features Given I

    go to “hotels/show/1” When I go to the single person page I should see 1 record Monday, May 27, 13
  15. Best Practices Features shouldn’t be stick to model implementation. They

    should describe the use case Given a person with name: ‘foo’, age: 18, gender: ‘male’, marital_status_extrange_field_name: ‘single’ When I go to the single person page I should see 1 record Given a single person When I go to the single person page I should see 1 record Monday, May 27, 13
  16. Best Practices Don’t abstract too much steps to reuse them

    along many features as this make you lose expressiveness. Given a person with name: ‘foo’, age: 18, gender: ‘male’, marital_status_extrange_field_name: ‘single’ When I go to the single person page I should see 1 record Given a single person When I go to the single person page I should see 1 record Monday, May 27, 13