Slide 1

Slide 1 text

Behavior Driven Development Monday, May 27, 13

Slide 2

Slide 2 text

Di erent types of testing Unit testing Integration test Acceptance test Low Level High Level Monday, May 27, 13

Slide 3

Slide 3 text

Unit testing Should be developer centric Should be easy to read Should not be fragile Should be maintainable Monday, May 27, 13

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

Unit testing WHITE BOX BLACK BOX Monday, May 27, 13

Slide 6

Slide 6 text

Unit testing WHITE BOX BLACK BOX Monday, May 27, 13

Slide 7

Slide 7 text

Unit testing WHITE BOX BLACK BOX Monday, May 27, 13

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Unit testing RSpec Test::Unit Minitest in Ruby Monday, May 27, 13

Slide 10

Slide 10 text

RSpec Its Behavior Oriented Uses custom DSL It just plain Ruby Monday, May 27, 13

Slide 11

Slide 11 text

RSpec Its Behavior Oriented Uses custom DSL It just plain Ruby Monday, May 27, 13

Slide 12

Slide 12 text

DEMO Monday, May 27, 13

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

Capybara DSL library to interact with web UI Plays nicely with Ruby testing frameworks Can define which driver uses Monday, May 27, 13

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

Useful gems DatabaseCleaner FactoryGirl TimeCop Faker Spork Poltergeist Monday, May 27, 13

Slide 22

Slide 22 text

DEMO Monday, May 27, 13

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Monday, May 27, 13