[rspec-users] Step matchers

James Hughes hughes.james at gmail.com
Mon Oct 15 13:11:08 EDT 2007


On 10/15/07, Wincent Colaiuta <win at wincent.com> wrote:
> El 15/10/2007, a las 14:21, "David Chelimsky" <dchelimsky at gmail.com>
> escribió:
>
> > On 10/15/07, Wincent Colaiuta <win at wincent.com> wrote:
> >>
> >> - The customer/client (not necessarily with any programming
> >> knowledge) writes the stories in a format which is (almost) plain
> >> text.
> >
> > Why almost? Because there is required syntax? We're asking them to be
> > able to write this:
> >
> > Story: employee accrues 1 day per month
> >
> >  As an employee
> >  I want to accrue 1 day per month during my first year
> >  So that I can replenish my self
> >
> >  Scenario: accrual after one month
> >    Given an employee
> >    When employee has worked 1 month
> >    Then employee should accrue 1 day vacation time
> >
> >  Scenario: accrual after 2 months
> >    Given an employee
> >    When employee has worked 2 months
> >    Then employee should accrue 1 days vacation time
>
> And as far as requirements go the leading whitespace could be treated
> as totally optional (because you can rest assured that people will
> get it wrong, use tabs instead of spaces, or spaces instead of tabs,
> or mix them up etc).
>
> >> - The developer then writes custom "step matchers"; where do they go?
> >
> > TBD. Probably in a directory under stories named steps or
> > step_matchers.
>
> My main concern here is that you're now having to keep two files in
> sync to have the stories work properly. The great thing about the
> Story Runner in its current form (and RSpec too) is that you can
> start off by writing a skeleton using a natural-language-like Ruby
> DSL, and then you flesh it out with code to fulfill its purpose. In
> other words, turn on code folding and a non-programmer can read it
> out loud and know what it means; turn off code folding and a
> programmer can see what's happening inside. It's great because your
> spec files are both readable by all and executable by the computer!
>

Just wanted to chime in and say, as a regular user of the folding
features of the editor, this is what really resonated with me when
Story Runner was first introduced. In fact, I recently did a short
presentation to some coworkers and did exactly what is described here:
put a story up with folding turned on to show the "story" without
accompanying code, and then opened up various folds to show the
implementation.

James

> But if your stories are stored in separate files, you no longer have
> that. If you edit the story you have to regenerate the story's
> specification in a way that preserves existing changes. Discrepancies
> between the files will break the stories. And on top of this you have
> to worry about a third place, the place where you define your step
> matchers (unless you define them in your "implementation" file, but
> you're still having to worry about two files then). So I am a little
> worried about this becoming very cumbersome and error-prone compared
> to the rest of RSpec.
>
> If I understand the proposals correctly then this will be great for
> non-programmer customers, but for programmers it will actually be
> awkward and uncomfortable, which would be a shame because one of
> RSpec's great selling points is that it makes TDD/BDD pleasant.
>
> I can't help but thinking that the best solution will be of the form:
>
> Story "..." do
>    Scenario "..." do
>      Given "..." do; end
>      And "..." do; end
>      When "..." do; end
>      Then "..." do; end
>    end
> end
>
> Where, whatever the format ends up being, the customer knows that the
> user-editable bits are the ones between the quotes, and the bits
> between "do" and "end" are for the programmer. I thought the proposal
> to have "strings like $this one" wasn't bad.
>
> > There are some pieces missing. Pat's initial description (the
> > beginning of this thread) recognizes Steps, but I'd like to see them
> > include the mechanics. Something like this:
> >
> >   matcher = StepMatcher.new("/^(.*) navigates to (.*)$") do
> >     login_as arg1
> >     get arg2
> >   end
> >
> > Then the runner would translate this:
> >
> >   When admin navigates to the user list
> >
> > to this:
> >
> >   find_when('admin navigates to the user list')
> >
> > which would find the matcher defined above and eventually do this:
> >
> >   matcher.run_step 'admin navigates to the user list'
> >
> > at which point 'admin' and 'the user list' would be extracted and
> > thrown at the block.
> >
> > Obviously there are pieces missing here, but I think that this could
> > prove very easy to use.
>
> I'd rather see:
>
> matcher = StepMatcher.new "$user navigates to $path" do |args|
>    login_as args[0]
>    get args[1]
> end
>
> Where StepMatcher can easily translate:
>
>    "$user navigates to $path"
>
> into a regex like:
>
>    /\A([^ ])+ navigates to ([^ ]+)\z/
>
> But I'd be even happier if this weren't stored in a separate file and
> were just part of the story file:
>
>    When "$user navigates to $path" do |args|
>      login_as args[0]
>      get args[1]
>    end
>
> Thanks for taking the time to explain all this, David!
>
> (And on a side note: I recently switched to the digest version of the
> mailing list, so I am aware that these replies aren't showing up as
> continuations of existing threads... sorry about that! Does anyone
> know of a way to avoid this when replying to the digest?)
>
> Cheers,
> Wincent
>
>
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the rspec-users mailing list