• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Getting Comfortable with BDD
 

Getting Comfortable with BDD

on

  • 6,177 views

Slides from the "Getting Comfortable with BDD" talk I gave a Nashville Barcamp 2009.

Slides from the "Getting Comfortable with BDD" talk I gave a Nashville Barcamp 2009.

Statistics

Views

Total Views
6,177
Views on SlideShare
6,168
Embed Views
9

Actions

Likes
15
Downloads
122
Comments
2

1 Embed 9

http://www.slideshare.net 9

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

12 of 2 previous next

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • @ambertch Thanks! I'll be giving revised versions of the Mongo talk at Ruby Midwest and Ruby Kaigi with updates on more in-depth implementations of Mongo.
    Are you sure you want to
    Your message goes here
    Processing…
  • haha! This slideshow is full of win - I attended your session at MongoSF and found this looking at those slides, good stuff...
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Getting Comfortable with BDD Getting Comfortable with BDD Presentation Transcript

  • Getting Comfortable with Behavior Driven Development Alex Sharp FrothLogic, Inc. ajsharp@frothlogic.com http://twitter.com/ajsharp
  • Speaking of “getting comfortable”...
  • I hope you get as comfortable with BDD as this guy is with EVERYTHING. Boom.
  • Why are you laughing?
  • Ok, but seriously.
  • Let’s talk about... • Things we’ll cover in this talk: 1. What is BDD? 2. Why you should care 3. How to start doing BDD with cucumber
  • So, what is BDD? • Behavior Driven Development (BDD) is a software development methodology that takes an outside-in approach to describe application behavior by encouraging intense customer involvement • Don’t worry, we’ll take this explanation from textbook to tolerable over the next 20-ish minutes...
  • So, what is BDD? • BDD borrows it’s core concepts, workflow and principles from it’s predecessor, Test Driven Development
  • In fact...
  • In fact... • BDD builds on top of Test Driven Development (TDD)
  • In fact... • BDD builds on top of Test Driven Development (TDD) • Which begs the question...
  • Well then what’s TDD?!
  • Well then what’s TDD?! • TDD == Write tests first, production code second
  • Well then what’s TDD?! • TDD == Write tests first, production code second • You’re TAFT, right!?
  • Well then what’s TDD?! • TDD == Write tests first, production code second • You’re TAFT, right!? • Main idea: Use test code to drive production code
  • Well then what’s TDD?! • TDD == Write tests first, production code second • You’re TAFT, right!? • Main idea: Use test code to drive production code • More on this later...
  • Well then what’s TDD?! • TDD/BDD Workflow • Red, Green, Refactor
  • Well then what’s TDD?! Not e:Ye llow text has absol utel y no r eleva nce • TDD/BDD Workflow here. • Red, Green, Refactor
  • Well then what’s TDD?!
  • Well then what’s TDD?! • TDD/BDD Workflow
  • Well then what’s TDD?! • TDD/BDD Workflow • Red, Green, Refactor
  • Well then what’s TDD?! • TDD/BDD Workflow • Red, Green, Refactor 1. Write a failing test
  • Well then what’s TDD?! • TDD/BDD Workflow • Red, Green, Refactor 1. Write a failing test 2. Write the smallest amount of production code possible to get that test to pass
  • Well then what’s TDD?! • TDD/BDD Workflow • Red, Green, Refactor 1. Write a failing test 2. Write the smallest amount of production code possible to get that test to pass 3. Refactor
  • Well then what’s TDD?! • TDD/BDD Workflow • Red, Green, Refactor 1. Write a failing test 2. Write the smallest amount of production code possible to get that test to pass 3. Refactor • i.e. add more tests and write better production code
  • Whoops, we forgot a step.
  • THINK, MAN, THINK! Don’t forget to think!!
  • THINK, MAN, THINK!
  • THINK, MAN, THINK! • The real TDD/BDD Workflow
  • THINK, MAN, THINK! • The real TDD/BDD Workflow • THINK, Red, Green, Refactor
  • THINK, MAN, THINK! • The real TDD/BDD Workflow • THINK, Red, Green, Refactor • Thinking is like, really important
  • THINK, MAN, THINK! • The real TDD/BDD Workflow • THINK, Red, Green, Refactor • Thinking is like, really important • It’s easy to forget to think when you can just start hacking L337 c0D3Z
  • THINK, MAN, THINK! • The real TDD/BDD Workflow • THINK, Red, Green, Refactor • Thinking is like, really important • It’s easy to forget to think when you can just start hacking L337 c0D3Z
  • THINK, MAN, THINK! k !! h in t t to ge n ’t for • The real TDD/BDD Workflow D o • THINK, Red, Green, Refactor • Thinking is like, really important • It’s easy to forget to think when you can just start hacking L337 c0D3Z
  • THINK, MAN, THINK! k !! h in t t to ge n ’t for • The real TDD/BDD Workflow D o • THINK, Red, Green, Refactor • Thinking is like, really important • It’s easy to forget to think when you can just start hacking L337 c0D3Z
  • Problem: Thinking is HARD.
  • Problem: Thinking is HARD. • Unfortunately, TDD, and the nature of traditional TDD tools often make it harder to think about what you’re trying to do.
  • BDD Picks up where TDD leaves off
  • BDD Picks up where TDD leaves off • TDD defines a really awesome workflow (think, red, green, refactor)
  • BDD Picks up where TDD leaves off • TDD defines a really awesome workflow (think, red, green, refactor) • BDD crystallizes some of the things that TDD leaves unclear or undefined.
  • BDD Picks up where TDD leaves off • TDD defines a really awesome workflow (think, red, green, refactor) • BDD crystallizes some of the things that TDD leaves unclear or undefined. • BDD == TDD 2.0
  • BDD Picks up where TDD leaves off • TDD defines a really awesome workflow (think, red, green, refactor) • BDD crystallizes some of the things that TDD leaves unclear or undefined. • BDD == TDD 2.0 • BDD bridges the gap between specs/ requirements and actual implementation
  • BDD Picks up where TDD leaves off
  • BDD Picks up where TDD leaves off • Programmer goals and priorities are more clearly aligned with requirements
  • BDD Picks up where TDD leaves off • Programmer goals and priorities are more clearly aligned with requirements • Why??
  • BDD Picks up where TDD leaves off • Programmer goals and priorities are more clearly aligned with requirements • Why?? • BDD is implemented in business language not programmer pig latin
  • Programmer pig latin
  • Programmer pig latin • 01010000 01110010 01101111 01100111 01110010 01100001 01101101 01101101 01100101 01110010 00100000 01110000 01101001 01100111 00100000 01101100 01100001 01110100 01101001 01101110
  • Come to think of it...
  • Come to think of it... • In doing this whole TDD/BDD thing, what exactly are we trying to do?
  • Come to think of it... • In doing this whole TDD/BDD thing, what exactly are we trying to do? • Test code?
  • Come to think of it... • In doing this whole TDD/BDD thing, what exactly are we trying to do? • Test code? • Describe behavior?
  • Come to think of it... • In doing this whole TDD/BDD thing, what exactly are we trying to do? • Test code? • Describe behavior? • Bill hours?
  • Come to think of it... • In doing this whole TDD/BDD thing, what exactly are we trying to do? • Test code? • Describe behavior? • Bill hours? • Bawl like ca$h money millionaires?
  • Come to think of it... • In doing this whole TDD/BDD thing, what exactly are we trying to do? • Test code? • Describe behavior? • Bill hours? • Bawl like ca$h money millionaires?
  • Come to think of it...
  • Come to think of it... • In doing this whole TDD/BDD thing, what are we “trying to do?” • Test code? • Describe behavior? • Bill hours? • Bawl like ca$h money millionaires?
  • Come to think of it... • In doing this whole TDD/BDD thing, what are we “trying to do?” How bout both, • Test code? AT THE SAME TIME!? • Describe behavior? • Bill hours? • Bawl like ca$h money millionaires?
  • Come to think of it... • In doing this whole TDD/BDD thing, what are we “trying to do?” How bout both, • Test code? AT THE SAME TIME!? • Describe behavior? • Bill hours? • Bawl like ca$h money millionaires?
  • Come to think of it... • In doing this whole TDD/BDD thing, what are we “trying to do?” How bout both, • Test code? AT THE SAME TIME!? • Describe behavior? • Bill hours? • Bawl like ca$h money millionaires?
  • Double-whammy
  • Double-whammy • We can describe the behavior we want first, and through that process, we drill down into lower level unit and functional tests for our code.
  • Double-whammy • We can describe the behavior we want first, and through that process, we drill down into lower level unit and functional tests for our code. • What’s the point of testing code before we pin down what that code should do?
  • Double-whammy • We can describe the behavior we want first, and through that process, we drill down into lower level unit and functional tests for our code. • What’s the point of testing code before we pin down what that code should do? • In other words, we need to define the behavior we want/expect before we go about testing it.
  • Dig deeper: What’s the goal of “testing” code? • Is it to test code or describe behavior?? Both. • TDD is about ensuring behavior. • BDD is about describing behavior. • First we describe the behavior, then we ensure that behavior works as expected.
  • The Fallacy of TDD
  • The Fallacy of TDD • Simply writing tests doesn’t necessarily yield any value
  • The Fallacy of TDD • Simply writing tests doesn’t necessarily yield any value • assert_equal(1, 1) # == true
  • The Fallacy of TDD • Simply writing tests doesn’t necessarily yield any value • assert_equal(1, 1) # == true • To be useful, our tests must have meaning, and that requires:
  • The Fallacy of TDD • Simply writing tests doesn’t necessarily yield any value • assert_equal(1, 1) # == true • To be useful, our tests must have meaning, and that requires: 1. Listening to our customers.
  • The Fallacy of TDD • Simply writing tests doesn’t necessarily yield any value • assert_equal(1, 1) # == true • To be useful, our tests must have meaning, and that requires: 1. Listening to our customers. 2. Thinking. Hard.
  • Problems with TDD
  • Problems with TDD
  • Problems with TDD 1. Unit and functional tests are exclusive to the “programmer domain”
  • Problems with TDD 1. Unit and functional tests are exclusive to the “programmer domain” • Bad for agile because we lose the customer-centric nature of agile at this point in the process
  • Problems with TDD 1. Unit and functional tests are exclusive to the “programmer domain” • Bad for agile because we lose the customer-centric nature of agile at this point in the process • Agile encourages deep customer involvement and interaction (as opposed to pre-defined requirements gathering phase)
  • Problems with TDD 1. Unit and functional tests are exclusive to the “programmer domain” • Bad for agile because we lose the customer-centric nature of agile at this point in the process • Agile encourages deep customer involvement and interaction (as opposed to pre-defined requirements gathering phase) • This breaks down when programmers start writing tests in programmer language
  • Problems with TDD
  • Problems with TDD 2. TDD tends to be associated with isolated tests
  • Problems with TDD 2. TDD tends to be associated with isolated tests • Unit and functional tests as opposed to integration tests
  • Problems with TDD 2. TDD tends to be associated with isolated tests • Unit and functional tests as opposed to integration tests • This is both good and bad (mostly bad though)
  • Problems with TDD 2. TDD tends to be associated with isolated tests • Unit and functional tests as opposed to integration tests • This is both good and bad (mostly bad though) • Good:
  • Problems with TDD 2. TDD tends to be associated with isolated tests • Unit and functional tests as opposed to integration tests • This is both good and bad (mostly bad though) • Good: • Tests run faster
  • Problems with TDD 2. TDD tends to be associated with isolated tests • Unit and functional tests as opposed to integration tests • This is both good and bad (mostly bad though) • Good: • Tests run faster • Tests are less brittle because not dependent on other parts of app
  • Problems with TDD 2. TDD tends to be associated with isolated tests • Unit and functional tests as opposed to integration tests • This is both good and bad (mostly bad though) • Good: • Tests run faster • Tests are less brittle because not dependent on other parts of app • Rarely the case with web apps
  • Problems with TDD 2. TDD tends to be associated with isolated tests • Unit and functional tests as opposed to integration tests • This is both good and bad (mostly bad though) • Good: • Tests run faster • Tests are less brittle because not dependent on other parts of app • Rarely the case with web apps • Bad:
  • Problems with TDD 2. TDD tends to be associated with isolated tests • Unit and functional tests as opposed to integration tests • This is both good and bad (mostly bad though) • Good: • Tests run faster • Tests are less brittle because not dependent on other parts of app • Rarely the case with web apps • Bad: • Tests become brittle due to excessive state setup (see next slide)
  • Problems with TDD
  • Problems with TDD 3. Writing isolated tests can feel contrived (again, especially in web apps), which often produces crappy test code, which results in crappier production code
  • Problems with TDD 3. Writing isolated tests can feel contrived (again, especially in web apps), which often produces crappy test code, which results in crappier production code • Typically happens when we have complex state setup (like a web app)
  • Problems with TDD 3. Writing isolated tests can feel contrived (again, especially in web apps), which often produces crappy test code, which results in crappier production code • Typically happens when we have complex state setup (like a web app) • Secondary problem: This “contrived- ness” pushes devs away from testing altogether, which is even worse.
  • Problems with TDD
  • Problems with TDD 4. A lot gets lost in translation due to these problems
  • Problems with TDD 4. A lot gets lost in translation due to these problems • Trying to translate customer conversations into test code is hard as it is
  • Problems with TDD 4. A lot gets lost in translation due to these problems • Trying to translate customer conversations into test code is hard as it is • Trying to overcome the frustration of writing seemingly contrived test cases makes it even harder
  • Problems with TDD 4. A lot gets lost in translation due to these problems • Trying to translate customer conversations into test code is hard as it is • Trying to overcome the frustration of writing seemingly contrived test cases makes it even harder • Frustration from testing leads to loss of focus and decreased productivity
  • Fear not, there is a better way
  • BDD
  • BDD • BDD takes an outside-in approach
  • BDD • BDD takes an outside-in approach • Starts at the user level, rather than programmer
  • BDD • BDD takes an outside-in approach • Starts at the user level, rather than programmer • In short, it’s a different way of thinking about and doing TDD
  • BDD • BDD takes an outside-in approach • Starts at the user level, rather than programmer • In short, it’s a different way of thinking about and doing TDD • Caveat
  • BDD • BDD takes an outside-in approach • Starts at the user level, rather than programmer • In short, it’s a different way of thinking about and doing TDD • Caveat • Technically, we could adapt our TDD tools to serve a BDD-like role, but we’ll still run into the problems just mentioned
  • Sweet BDD Diagram.
  • Sweet BDD Diagram.
  • Sweet BDD Diagram. Customer requireme nts
  • Sweet BDD Diagram. Customer requireme nts Custom er requi rements
  • Sweet BDD Diagram. Customer requireme nts Cu s to me rr eq uir em en ts Custom er requi rements
  • Sweet BDD Diagram. Customer requireme nts Cu s to me rr eq uir em en ts n ts e em quir r re e m s to Custom Cu er requi rements
  • Sweet BDD Diagram. Customer requireme nts Cu BDD (integration tests) s to me rr eq uir em en ts n ts e em quir r re e m s to Custom Cu er requi rements
  • Sweet BDD Diagram. Customer requireme nts Cu BDD (integration tests) s to me rr eq uir em en ts n ts e em quir BDD (integration tests) re e r m s to Custom Cu er requi rements
  • Sweet BDD Diagram. Customer requireme nts Cu BDD (integration tests) s to me rr eq uir em TDD (unit/functional en tests) ts n ts e em quir BDD (integration tests) re e r m s to Custom Cu er requi rements
  • Sweet BDD Diagram. Customer We start at the requireme nts outside and drill down, inwards Cu towards unit and BDD (integration tests) s to functional tests me rr eq uir em TDD (unit/functional en tests) ts n ts e em quir BDD (integration tests) re e r m s to Custom Cu er requi rements
  • Sweet BDD Diagram. Customer We start at the requireme nts outside and drill down, inwards Cu towards unit and BDD (integration tests) s to functional tests me rr eq uir By now you might be em TDD (unit/functional thinking, “Aren’t en tests) these just integration ts n ts tests showed through e em a totally awesome quir diagram?” BDD (integration tests) re e r m s to Custom Cu er requi rements
  • Sweet BDD Diagram. Customer We start at the requireme nts outside and drill down, inwards Cu towards unit and BDD (integration tests) s to functional tests me rr eq uir By now you might be em TDD (unit/functional thinking, “Aren’t en tests) these just integration ts n ts tests showed through e em a totally awesome quir diagram?” BDD (integration tests) re e r m Yes. s to Custom Cu er requi rements
  • Sweet BDD Diagram. Customer We start at the requireme nts outside and drill down, inwards Cu towards unit and BDD (integration tests) s to functional tests me rr eq uir By now you might be em TDD (unit/functional thinking, “Aren’t en tests) these just integration ts n ts tests showed through e em a totally awesome quir diagram?” BDD (integration tests) re e r m Yes. s to Custom Cu er requi rements
  • Sweet BDD Diagram. Customer We start at the requireme nts outside and drill down, inwards Cu towards unit and BDD (integration tests) s to functional tests me rr eq uir By now you might be em TDD (unit/functional thinking, “Aren’t en tests) these just integration ts n ts tests showed through e em a totally awesome quir diagram?” BDD (integration tests) re e r m Yes. s to Custom Cu er requi rements
  • Sweet BDD Diagram. Customer We start at the requireme nts outside and drill down, inwards Cu towards unit and BDD (integration tests) s to functional tests me rr eq uir By now you might be em TDD (unit/functional thinking, “Aren’t en tests) these just integration ts n ts tests showed through e em a totally awesome quir diagram?” BDD (integration tests) re e r m Yes. s to Custom Cu er requi rements
  • Sweet BDD Diagram. Customer We start at the requireme nts outside and drill down, inwards Cu towards unit and BDD (integration tests) s to functional tests me rr eq uir By now you might be em TDD (unit/functional thinking, “Aren’t en tests) these just integration ts n ts tests showed through e em a totally awesome quir diagram?” BDD (integration tests) re e r m Yes. s to Custom Cu er requi rements
  • Dig deeper: What’s the point of testing code? • Is it to test code or describe behavior??
  • Dig deeper: What’s the point of testing code? • Is it to test code or describe behavior?? Both.
  • Workflow • Describe code with cucumber integration tests • Use Red, Green, Refactor • As you go through this process, write unit and functional tests along the way
  • Sample Cucumber Feature
  • Sample Cucumber Feature Feature: User login Scenario: A registered user attempts to login Given I am a registered user with login "ajsharp" and password "secret" When I go to the user login page And I fill in "Login" with "ajsharp" And I fill in "Password" with "secret" And I click the "Log In" button Then I should be redirected to my profile page And I should see "ajsharp's profile"
  • Sample Cucumber Feature
  • Sample Cucumber Feature BDD Outside-in Workflow • Cucumber feature
  • Sample Cucumber Feature Feature: User login Scenario: A registered user attempts to login Given I am a registered user with login "ajsharp" and password "secret" BDD Outside-in Workflow • Cucumber feature
  • Sample Cucumber Feature Feature: User login Scenario: A registered user attempts to login Given I am a registered user with login "ajsharp" and password "secret" BDD Outside-in Workflow • Cucumber feature
  • Sample Cucumber Feature Feature: User login Scenario: A registered user attempts to login Given I am a registered user with login "ajsharp" and password "secret" BDD Outside-in Workflow • Cucumber feature
  • Sample Cucumber Feature Feature: User login Scenario: A registered user attempts to login Given I am a registered user with login "ajsharp" and password "secret" BDD Outside-in Workflow • Cucumber feature From here, cucumber looks “step definition” files that match (via regular expressions -- shout out Perl) the statements in your .feature file.
  • Sample Cucumber Feature BDD Outside-in Workflow • Cucumber feature From here, cucumber looks “step definition” files that match (via regular expressions -- shout out Perl) the statements in your .feature file.
  • Sample Cucumber Feature BDD Outside-in Workflow • Cucumber feature From here, cucumber looks “step definition” files that match (via regular expressions -- shout out Perl) the statements in your .feature file. Next Step: Write a failing test
  • Cucumber step definition file
  • Cucumber step definition file BDD Outside-in Workflow • Cucumber feature • Step Definition
  • Cucumber step definition file Given /^I am a registered user with username "(.+)" and password "(.+)"$/ do |login, pass| @user = User.create!(:username => login, :password => pass) end BDD Outside-in Workflow • Cucumber feature • Step Definition
  • Cucumber step definition file Given /^I am a registered user with username "(.+)" and password "(.+)"$/ do |login, pass| @user = User.create!(:username => login, :password => pass) end BDD Outside-in Workflow • Cucumber feature • Step Definition We haven’t implemented the User model yet, so let’s do that....
  • Cucumber step definition file Given /^I am a registered user with username "(.+)" and password "(.+)"$/ do |login, pass| @user = User.create!(:username => login, :password => pass) end BDD Outside-in Workflow • Cucumber feature • Step Definition We haven’t implemented the User model yet, so let’s do that.... But wait!! To implement the User model, we need to write some unit tests for it....Red, Green, Refactor
  • Cucumber step definition file Given /^I am a registered user with username "(.+)" and password "(.+)"$/ do |login, pass| @user = User.create!(:username => login, :password => pass) end BDD Outside-in Workflow • Cucumber feature • Step Definition We haven’t implemented the User model yet, so let’s do that.... But wait!! To implement the User model, we need to write some unit tests for it....Red, Green, Refactor Next Step: Green - To make the cucumber step pass (higher level, more outside) we need to do Red - write failing tests for user model (lower level, more inside)
  • User Model Unit Test (or spec, in this case)
  • User Model Unit Test (or spec, in this case) describe User do it { should validate_presence_of :username } it { should validate_presence_of :password } end
  • User Model Unit Test (or spec, in this case) describe User do BDD Outside-in Workflow it { should validate_presence_of :username } it { should validate_presence_of :password } • Cucumber feature end • Step Definition • User model unit test/spec
  • User Model Unit Test (or spec, in this case) describe User do BDD Outside-in Workflow it { should validate_presence_of :username } it { should validate_presence_of :password } • Cucumber feature end • Step Definition • User model unit test/spec
  • User Model Unit Test (or spec, in this case) describe User do BDD Outside-in Workflow it { should validate_presence_of :username } it { should validate_presence_of :password } • Cucumber feature end • Step Definition • User model unit test/spec This will fail, because we haven’t written any production code yet
  • User Model Unit Test (or spec, in this case) describe User do BDD Outside-in Workflow it { should validate_presence_of :username } it { should validate_presence_of :password } • Cucumber feature end • Step Definition • User model unit test/spec This will fail, because we haven’t written any production code yet Next Step: Green - Make our model unit tests pass by writing some production code
  • User Model Unit Test (or spec, in this case) class User < ActiveRecord::Base validates_presence_of :username validates_presence_of :password end
  • User Model Unit Test (or spec, in this case) class User < ActiveRecord::Base validates_presence_of :username BDD Outside-in Workflow validates_presence_of :password end • Cucumber feature • Step Definition • User model unit test/spec • User model production code
  • User Model Unit Test (or spec, in this case) class User < ActiveRecord::Base validates_presence_of :username BDD Outside-in Workflow validates_presence_of :password end • Cucumber feature • Step Definition • User model unit test/spec • User model production code
  • User Model Unit Test (or spec, in this case) class User < ActiveRecord::Base validates_presence_of :username BDD Outside-in Workflow validates_presence_of :password end • Cucumber feature • Step Definition • User model unit test/spec • User model production code This will make our unit tests pass. Nice.
  • User Model Unit Test (or spec, in this case) class User < ActiveRecord::Base validates_presence_of :username BDD Outside-in Workflow validates_presence_of :password end • Cucumber feature • Step Definition • User model unit test/spec • User model production code This will make our unit tests pass. Nice. “Bubble up” back to the cucumber .feature as our unit/functional tests pass
  • Awesome workflow • This workflow keeps us focused on building business value in our code for our customers • i.e. customer requirements
  • Resources • BDD • http://behaviour-driven.org/ • Cucumber • http://cukes.info • http://github.com/aslakhellesoy/cucumber • Rspec Beta Book • http://pragprog.com/titles/achbd/the-rspec- book
  • Resources • My Blog • http://alexjsharp.com • I’ll post these slides there • My github account • http://github.com/ajsharp • Questions? • ajsharp@frothlogic.com