[Rspec-users] *what* to test?

Mike Pence mike.pence at gmail.com
Sun Oct 15 19:20:59 EDT 2006


Thank you both so much. Very, very helpful.


On 10/15/06, aslak hellesoy <aslak.hellesoy at gmail.com> wrote:
> On 10/15/06, Mike Pence <mike.pence at gmail.com> wrote:
> > So I dig rspec and BDD, of course. I thought that Dave's Google Video
> > was a great intro () -- even if it was a bit heavy on theory and a bit
> > loose on the nuts and bolts. But I don't see anyone sufficiently
> > answering the big question:
> >
> > What do you test? How do you define higher level and lower level
> > behaviors that should have tests written for them?
>
> I'm going to be elaborate here. There is no quick answer. Here is how
> I teach it:
>
> Start by asking yourself (or better - whomever wants the software):
> "what do you want to accomplish with the software".
>
> Try to come up with simple tasks that you can do with the software and
> elaborate each of those. These are called User Stories (look it up).
> Here is an example of a User Story for someone who wants to play
> bowling:
>
> == See total score ==
> As a player
> I want to see the total score at the end of the game
> So that I can compare scores with other players and my own personal record
>
> What you see here is the Narrative of the User Story. It's not enough
> to leap into BDD/TDD yet, but a good starting point. Now, write down
> some Acceptance Criteria for the User Story. The purpose of Acceptance
> Criteria is to help the programmers know When They Are Done. A second
> (and very important role) of Acceptance Criteria is that they are the
> primary input for the spec writing activity.
>
> I recommend that Acceptance Ariteria be written in a Given-When-Then
> style (GWT). Each one of them should be an example of how the software
> should work. They are meant to be examples.
>
> == Acceptance Criteria ==
> The programmer will know when (s)he is done when:
>
> Given I have a new game # Initial known state
> When I throw all balls in the gutter # An action or event
> Then the final score should be zero # An observable outcome
>
> Given I have a new game
> When I knock down 3 pins, then all balls in the gutter
> Then the final score should be 3
>
> Given I have a new game
> When I knock down 3 pins, then 7, then 2, then all balls in the gutter
> Then the final score should be 14
>
> etc.
>
> Try to come up with really simple acceptance criteria (examples) and
> make them gradually more complex. You'll start developing specs to
> satisfy the simple ones first.
>
> Let's turn the first Acceptance Criterion (for the gutter game) into a spec:
>
> context "An empty game" do # This is the "Given"
>   specify "should give zero score when all balls go in the gutter" do
> # This is the When+Then
>     game = Game.new
>     (1..20).each do
>       game.roll(0)
>     end
>     game.score.should_be 0
>   end
> end
>
> This is all the code you have. You haven't written the Game class yet.
> The spec expresses the first GWT acceptance criterion, and as you see,
> it's a fairly verbatim translation of it. When you run it you'll get
> the following error:
>
> NameError in 'An empty game should give zero score when all balls go
> in the gutter'
> uninitialized constant Game
>
> Hooray. That is good. It's good because RSpec is now telling you what
> to do next. You'll implement the Game class:
>
> class Game
> end
>
> Run the spec again and see it fail with a new error message:
>
> NoMethodError in 'An empty game should give zero score when all balls
> go in the gutter'
> undefined method `roll' for #<Game:0x3e85d8>
>
> Now, define it:
>
> class Game
>   def roll(pins)
>   end
> end
>
> Run the spec again:
>
> NoMethodError in 'An empty game should give zero score when all balls
> go in the gutter'
> undefined method `score' for #<Game:0x3e85d8>
>
> And fix it:
>
> class Game
>   def roll(pins)
>   end
>
>   def score
>     0
>   end
> end
>
> Run the spec again and see it pass. You have satisfied the first
> acceptance criterion. You now have a bowling game that will correctly
> calculate the score for people who always throw the balls in the
> gutter.
>
> Now you attack the next acceptance criterion.
>
> In the real world you'll have more complex things than this of course,
> but the approach can be the same. Start at the high level and drill
> down. Start with something that is at the border of your system -
> something that can be verified by an end user. Let the guts evolve
> gradually, and let them evolve from functional user stories.
>
> I highly recommend doing the Bowling Game Kata (from which this intro
> was inspired):
> http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata. It's
> trivial programming, but a mind-bending excercise for those who are
> unfamiliar with TDD and BDD.
>
> Cheers,
> Aslak
>
> > _______________________________________________
> > Rspec-users mailing list
> > Rspec-users at rubyforge.org
> > http://rubyforge.org/mailman/listinfo/rspec-users
> >
>


More information about the Rspec-users mailing list