I am specing a feature, maybe at more high level of what it should be,
and this makes scenarios that involves more that one rails controller.
Is it possible or convenient?
I have scenarios like this (although it’s only an unreal example):
Feature: Making a reservation for a service.
Scenario: Making the reservation
Given I want to make a reservation for a service
When I choose the service
Then I see the page ‘service1/1/options’
When I select option 1
And I click on “submit”
Then I will be asked for a confirmation
When I answer ‘Yes’
Then I see “Ok”
And I go to “/services/1”
Is this ok or I should define the features with only one single
iteration?
When I choose the service
iteration?
It’s OK to have more than one series of When/Then as long as they make
for a cohesive scenario, which you’ve done here.
I’d recommend avoiding URLs in the steps though. For example (I don’t
know what service and option mean in your case, but this should give
you an idea):
Scenario: Make a new reservation
Given a ‘Foo’ service
And the ‘Foo’ service includes a ‘Bar’ option
When I choose the ‘Foo’ service
Then I see the ‘Foo Service’ detail
When I select the ‘Bar’ option
And I submit my request
Then I am be asked for a confirmation
When I answer ‘Yes’
Then I see ‘OK’
And I see the ‘Foo’ service in the ‘My Services’
Note the lack of references to URLS and even pages. I might have taken
it too far, depending on your situation. For example, “And I submit my
request” instead of “And I click ‘submit’” - If there is particular
text on the button that is deemed to have business value, then you
might say “And I click ‘Request Service’” - but if you’re referencing
DOM IDs or HTML element names like ‘submit’, I’d hide those.
All make a lot of sense.
With the urls I only was trying to clarify that the scenario spans
across multiple controllers, but I am making the specs as you recommend.
I am specing a feature, maybe at more high level of what it should be,
and this makes scenarios that involves more that one rails controller.
Is it possible or convenient?
I do not think its a problem touching multiple controllers if that’s
what is required for the user to achieve some specific value from the
system. The value is king.
When I answer 'Yes'
Then I see "Ok"
And I go to "/services/1"
Is this ok or I should define the features with only one single
iteration?
I find deviating from the ordering of Given/When/Then can sometimes
produce scenarios that are hard to read and conceptualise. So I
personally avoid multiple iterations in a single scenario. This however
does not mean you should not touch multiple controllers.
I would suggest perhaps something like this for your example scenario:
–
Scenario: Making a successful reservation for massage service
Given I have gone to the reservation page
And I selected the service “massage”
When I choose the option “extra oil”
And I press the “make reservation” button
And I confirm my reservation
Then I will see “Ok, your reservation has been made for blah.
Thanks!”
And I will see the total price
And I will be redirected to the service.
Scenario: Making a reservation but cancelling at confirmation
–
My scenario would still fail based on the ‘thens’ you mention. For
example if I don’t see the page ‘service1/1/options’ then I can never
click the option for extra oil. So your thens have become implied. They
are part of the journey, the destination (and value) is seeing I’ve made
a reservation.
Looking at your initial steps this one jumps out at me:
Given I want to make a reservation for a service
While it gives intent and a goal it does not explain the start state so
I would question its usefulness. It feels more like the scenario name.
required for the user to achieve some specific value from the system. The
value is king.
To add this Joseph’s comment, a general rule of thumb I follow is that
I don’t think about what controllers (if any) my scenarios are going
to use. Since the scenario communicates value and behaviour provided
by the app it’s up to me as the developer to determine a good
implementation. This may involve multiple controllers, one controller,
or no controllers.
This doesn’t mean that I don’t have a general idea of how I’m going to
implement something because I usually do. But that’s just because I’m
a developer and as soon as I see a behaviour wanting implementation my
brain goes in problem solving mode and starts to determining possible
paths to a solution. The trick is to not to let this influence how you
write (or encourage customers if you’re working with them) scenarios.
Here’s a quick example. Let’s say that you start by thinking one
controller will suffice so you write your scenario for one controller.
As you implement the scenario you may determine you really want to
have two controllers because it helps keep your controller
implementations clean. At this point you shouldn’t have to change your
scenario because you didn’t change what the app is doing – you just
changed how it is doing it. So, changes should be limited to step
definitions and actual implementation and not the scenario text
itself.
Then I will be asked for a confirmation
scenarios that are hard to read and conceptualise. So I personally avoid
And I press the “make reservation” button
the journey, the destination (and value) is seeing I’ve made a reservation.
–
text on the button that is deemed to have business value, then you
might say “And I click ‘Request Service’” - but if you’re referencing
DOM IDs or HTML element names like ‘submit’, I’d hide those.
However we could get a lot of re-use in the user steps if we have
step definitions like these:
When /^clicks ‘(+)’ link$/ do |text|
browser.link(:text, Regexp.new(value)).click
end
When /^clicks ‘(+)’ button$/ do |text|
browser.button(:value, Regexp.new(value)).click
end
When clicks ‘Submit’ link
When clicks ‘Submit’ button
When clicks ‘New’ link
When clicks ‘New’ button
I personally don’t think it is a crime for the tester to change the
acceptance steps as long as the ‘user’ can easily follow the
narrative.
A lot of the other user-steps could be wrapped-up in a more
‘declarative’ fashion.
On Wed, Jan 21, 2009 at 9:27 AM, aidy lewis [email protected]
wrote:
When /^clicks ‘(+)’ link$/ do |text|
When clicks ‘New’ link
When clicks ‘New’ button
The important part of what I was saying was to avoid hidden elements
(DOM IDs and element names). If the label that is visible in the
browser says “Submit”, then this is OK IMO.
I personally don’t think it is a crime for the tester to change the
acceptance steps as long as the ‘user’ can easily follow the
narrative.
Don’t worry, you’re not under arrest. At least not for this
transgression
Assuming that your steps are focused on using DOM Id’s what sort of
convention would you use to translate from the narrative of the step to
the
DOM id.
Would you avoid the brittleness that “clicks submit link|button” has
over “I
submit”. Thats me arguing that whether its a link or a button, and
whether
the user submits by clicking, pressing enter or barking is not relevant
to
the scenario.
Would you avoid the brittleness that “clicks submit link|button” has over “I submit”.
There are often many ways of submitting on the same page. So to avoid
tying “I submit” to a particular scenario, I tend to use “I click
‘submit’”, which doesn’t correspond to a link or button specifically,
but to “a link, button, or label with the text ‘submit’ – and raise
an error if it’s ambiguous”. Is that too vague? As a human, if I were
told to “click ‘submit’” I think I would apply the same reasoning.
Would you avoid the brittleness that “clicks submit link|button” has over “I submit”.
There are often many ways of submitting on the same page. So to avoid
tying “I submit” to a particular scenario, I tend to use “I click
‘submit’”, which doesn’t correspond to a link or button specifically,
but to “a link, button, or label with the text ‘submit’ – and raise
an error if it’s ambiguous”. Is that too vague? As a human, if I were
told to “click ‘submit’” I think I would apply the same reasoning.
Yes, and in a lot of cases we do choose ‘I click submit’ with the step
implementation searching for a button value or text link: however, the
user may specify a link; so I would write ‘I click the ‘submit’ link’.
Aidy
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.