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
> >
>