[rspec-users] Before and After blocks for individual feature files?

Ben Mabey ben at benmabey.com
Wed Apr 29 01:47:13 EDT 2009


Julian Leviston wrote:
> Hey Ben,
>
> It'd be kinda cool if there was a sort of before and after for a 
> feature rather than each scenario. Is there?

Nope.  There is no before(:all) equivalent in cucumber.  Just the Before 
and After hooks, which are for scenarios.. and Backgrounds which are 
just for scenarios on the given feature.
>
> (Rails context) We often need this. It'd be really helpful for things 
> like when we want to test about 15 things on a particular web page, 
> and they don't require fresh data. We end up with a login and setup 
> type background which gets run every time rather than simply once.
 In the context of webrat a before(:all) would not help you a whole lot 
since each scenario starts with a new session (so you have to login each 
time, for example).  I understand the argument for complex data setup 
though.  Having the same setup ran for each scenario can get costly.  I 
haven't felt enough pain though to really justify adding something like 
that.  Cleanup would be messy because we couldn't wrap it all in a 
transaction AFAIK, so you would have to have an after(:all) like method 
to clean up the feature.  For complex data that I rely on all the time I 
tend to load it once with fixtures at boot up time within env.rb.  This 
is usually for look-up data... but if you were really concerned about 
record creation you could do something similar.  The question is if the 
additional complexity of keeping all that global state in your head 
worth the faster execution time.  For me it generally is not.
>
> I guess we could refactor it into a set of examples perhaps... would 
> that work? It just strikes me as quite complicated. It'd be awesome if 
> we had sub-scenarios (and they could be specified to levels) ;-) 
> Perhaps I'm just being too complicated.

I would need more context to really answer your question.  However, can 
I ask if your scenarios are written in a declarative or imperative 
fashion[1]?  If they are written declaratively, or at least partly, then 
you can specify a lot more behavior in a step without adding too much 
noise to the scenario.  Another thing I should point out is that you 
don't need to, and you shouldn't, test everything on the Cucumber 
level.  For complex views, for example, it may be easier to do RSpec 
examples (view specs) and just use Cucumber to test the basics.  In 
general, I'm pretty wary about sub-scenarios and the like.  They could 
be powerful, but they could very easily get complicated and turn 
scenarios into a giant mess that only programmers could understand.  
Feel free to share any ideas you have on the subject though and we'll 
see what the tradeoffs are.  We love throwing new ideas around on the 
list. :)
>
> I loved your rubyconf talk presentation, BTW. We kinda took exception 
> to the bit where you said "Selenium just works", though. There are a 
> number of things where the connection between selenium and webrat is a 
> little tenuous and finicky about.

Thanks!  Yeah, the selenium adapter in webrat isn't nearly as mature as 
the rails adapter. :(  I haven't had a lot of issues with it, but I try 
to use it as least as possible and have only really used it on simple 
things.  And to be honest, I haven't used it since January.  So, YMMV.
>
> Also we seem to be having timing issues for AJAX requests with 
> Selenium. Webrat doesn't seem to want to wait until the AJAX request 
> as finished before doing the next thing. Any ideas here? 
I think I have seen people in #webrat on irc.freenode.net talk about 
that and how they've had to add additional wait commands in. But, I 
really don't know any details.  Sorry!  Your best bet is to ask in 
#webrat, or on it's google group or lighthouse account.

-Ben

1. 
http://www.benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories/
>
> On 29/04/2009, at 4:28 AM, Ben Mabey wrote:
>
>> Arco wrote:
>>> I'd like to do this:
>>>
>>> Feature: user signup
>>> Before:
>>>   Given I have a cleaned up database
>>> Scenario Outline: Sign Up
>>>   Given I am on the signup page
>>>   When I sign up using <userid>
>>>   Then I should see <message>
>>>  Examples:
>>>   |userid     |message           |
>>>   |userX      |successful signup |
>>>   |userX      |duplicate userid  |
>>>
>>> "I have a cleaned up database" runs before every example, making the
>>> second example ('duplicate userid') fail.
>>>
>>
>>
>> You could use Background and it would work just like you want it to:
>>
>> Feature: user signup
>> Background:
>>  Given I have a cleaned up database
>> Scenario Outline: Sign Up
>>  Given I am on the signup page
>>  When I sign up using <userid>
>>  Then I should see <message>
>> Examples:
>>  |userid     |message           |
>>  |userX      |successful signup |
>>  |userX      |duplicate userid  |
>>
>>
>> However, I would not encourage this.  You should try to avoid using 
>> technical words, such as database, in your features.  If anything you 
>> could say "Given no users exist" or something like that.  Keeping 
>> your database clean is something you generally want for every 
>> scenario though.  So I would suggest putting the code in your "Given 
>> I have a cleaned up database" code into a Before block.  The wiki has 
>> a page on using the Before hook: 
>> http://wiki.github.com/aslakhellesoy/cucumber/hooks
>>
>> Basically, in your env.rb file you will add something like:
>>
>> Before do
>> Database.clean! # or however you clean your DB
>> end
>>
>>
>>
>> HTH,
>> Ben
>>
>>
>>> On Apr 28, 9:38 am, aslak hellesoy <aslak.helle... at gmail.com> wrote:
>>>
>>>> On Tue, Apr 28, 2009 at 6:15 PM, Arco <akl... at gmail.com> wrote:
>>>>
>>>>> OK - I found a workaround.  I simply tag the first scenario with
>>>>> '@first', then
>>>>> do Before('@first') and i get what I want - executing a block once 
>>>>> for
>>>>> the feature file.
>>>>>     Except for one problem:  most of my scenarios are done as 
>>>>> scenario
>>>>> outlines, which
>>>>> are run multiple times - once for each row of my Example table.
>>>>>     A workaround to that problem might be to put a 'dummy' 
>>>>> scenario that
>>>>> is run before the other scenarios in my feature file...
>>>>>      @first
>>>>> Scenario: Call a before block before running other scenarios...
>>>>>     But this puts junk in my feature files.  Is there a better, 
>>>>> cleaner
>>>>> way??
>>>>>
>>>> a) Why do you need one thing to happen before a feature?
>>>> b) Why can't you do it before each scenario?
>>>>
>>>> Aslak
>>>>
>>>>
>>>>
>>>>
>>>>> On Apr 28, 8:32 am, Arco <akl... at gmail.com> wrote:
>>>>>
>>>>>> I also would like a hook that executes a block once before running a
>>>>>> feature file.
>>>>>>       In my testing i found that:
>>>>>> - Background: executes before each scenario
>>>>>> - Before executes before each scenario
>>>>>> - Before('@tag') executes before each scenario
>>>>>>       Is there a way to execute a block once before each feature, 
>>>>>> but not
>>>>>> before each scenario?
>>>>>>       On Apr 28, 7:08 am, aslak hellesoy 
>>>>>> <aslak.helle... at gmail.com> wrote:
>>>>>>
>>>>>>>> Hi -- is it possible to set before and after blocks for individual
>>>>>>>>
>>>>> feature
>>>>>
>>>>>>>> files?
>>>>>>>>
>>>>>>> Yes. Use tagged hooks:
>>>>>>>
>>>>> http://wiki.github.com/aslakhellesoy/cucumber/hooks
>>>>>
>>>>>>> Aslak
>>>>>>>
>>>>>>>> I've tried putting them in step files, but they just get called
>>>>>>>>
>>>>> before
>>>>>
>>>>>>>> everything, like they'd been declared in env.rb, which is 
>>>>>>>> consistent
>>>>>>>>
>>>>> with
>>>>>
>>>>>>>> how I thought cucumber worked, but I thought I'd best try it 
>>>>>>>> anyway.
>>>>>>>> Anyway, I have some features that require a specific state be 
>>>>>>>> set up
>>>>>>>>
>>>>> before
>>>>>
>>>>>>>> they run -- is this possible to do, and how would I go about doing
>>>>>>>>
>>>>> it?
>>>>>
>>>>>>>> Thanks for any & all help,
>>>>>>>>  Doug.
>>>>>>>>           _______________________________________________
>>>>>>>> rspec-users mailing list
>>>>>>>> rspec-us... at rubyforge.org
>>>>>>>> http://rubyforge.org/mailman/listinfo/rspec-users
>>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> rspec-users mailing list
>>>>>>> rspec-us... at rubyforge.orghttp://
>>>>>>>
>>>>> rubyforge.org/mailman/listinfo/rspec-users
>>>>>
>>>>>> _______________________________________________
>>>>>> rspec-users mailing list
>>>>>> rspec-us... at rubyforge.orghttp://
>>>>>>
>>>>> rubyforge.org/mailman/listinfo/rspec-users
>>>>> _______________________________________________
>>>>> rspec-users mailing list
>>>>> rspec-us... at rubyforge.org
>>>>> http://rubyforge.org/mailman/listinfo/rspec-users
>>>>>
>>>>
>>>> _______________________________________________
>>>> rspec-users mailing list
>>>> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users 
>>>>
>>>>
>>> _______________________________________________
>>> rspec-users mailing list
>>> rspec-users at rubyforge.org
>>> http://rubyforge.org/mailman/listinfo/rspec-users
>>>
>>
>> _______________________________________________
>> rspec-users mailing list
>> rspec-users at rubyforge.org
>> http://rubyforge.org/mailman/listinfo/rspec-users
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users



More information about the rspec-users mailing list