James,James,
Ok I think I get what your saying. You seem to be quite focused on the
idea of having quotes around variables in features subsequently in
matchers and connecting this with calls in steps to steps. I think
there two separate topics. Anyhow I wrote the following to try and
explain things a bit better. I hope its
- reasonably accurate
- helpful
All best
Andrew
Cucumber decides what you want it to do by comparing things you want
to happen which are defined in strings, and matching these with ruby
code (defined in steps) via regular expressions. The main way this
happens is between strings in feature files and steps in step
definitions. However it can also happen when one step definition
“calls” another. Feature files only contain strings so you don’t need
any quotes in them. However when you “call” a step from within a step
you have to use quotes to differentiate the string that is going to be
matched from the rest of the ruby code in the step.
The regular expressions defined in step files can have many different
matchers. A top tip I got from Aslak was to use Rubular
(www.rubular.com) to explore things. One of the things we need to with
our regex’s is capture “variables” in our features. Initially we see
(.) being used in the regex for capturing these. However (.) is a
really crude capture device. I think this crudeness is why we quite
often get the idea of using quotes around the variable and the capture
device. However IMO its much better to use slightly subtle captchers
in your steps and keep the features cleaner. Feature writers shouldn’t
be expected to understand the concept of variables and don’t need to
be dealing with putting quotes around things. (just my opinion and
contradicted by the common_webrat steps, but I think the quotes there
are a bit of a hangover from the old story matcher)
Some simple capture examples might help
(\d+) # capture an integer (any number of numeric characters)
product[s] # optionally capture a plural. This matches ‘product’ and
‘products’
(?:the|my) # match either ‘the’ or ‘my’ but also don’t ignore the
variable captured (done by ? e.g. so you don’t have to have this
argument if you use more examples in a table
Now you can write steps that make things convenient for the feature
writer and precise enough for the step writer. You can also make your
regex’s so complicated that only 4 people on the planet can understand
them! You have to balance the benefits against this complexity.
One of my more complex captures so far is
/^there (?:is|are) (\d+)(?:\s*|\s*more\s*)product[s]?$/
this is to get only number of products as a variable and give the
flexibility to match
Given there is 1 product
Given there are 2 products
Given there are 4 more products
Given there are 4 more products
Better might be
/^there (?:is|are) (\d+) (?:more\s)?product[s]?$
this won’t match
Given there are 4 more products
but will match the other steps and is a bit simpler
Writing and using regular expressions is an art in itself and one
that’s very useful in Ruby programming in general. One of the side
effects I’ve found from using Cucumber is getting a gentle and useful
introduction to this arcane topic.
2008/12/1 James B. [email protected]: