[rspec-users] Step matchers

David Chelimsky dchelimsky at gmail.com
Mon Oct 15 10:51:28 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!
>
> 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

Part of this is to separate the programming 'noise' from the text, so
if we do head down this path (which remains to be seen) I doubt these
would end up in the same file.

>
> Thanks for taking the time to explain all this, David!

Well, it's more like exploring at this point. None of this is written
in anything but the 1s and 0s in this thread.

But you're welcome!

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