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

Ben Mabey ben at benmabey.com
Tue Apr 28 18:44:11 EDT 2009


Arco wrote:
> Thanks for your reply Ben.  +1 on your wording recommendation - I
> understand and agree 100%
>
> However - for me - the Background block executes before each example
> in the table.  Therefore, the database is cleared twice, and the
> second example ('duplicate userid') fails.
>
> (Cucumber 0.3.1 / ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin])
>
> Here are some snippets from a little workaround that i've employed...
> in env.rb:
>   State = {'feature_file'=>'initialize'}
> in my_steps.rb:
>   unless State['feature_file'] ==
> @__cucumber_current_step.file_colon_line.split(':').first
>     puts "CLEANUP CODE HERE - RUN ONCE PER FEATURE FILE  --------"
>   end
>   State['feature_file'] =
> @__cucumber_current_step.file_colon_line.split(':').first
>
> I'm sure there must be a better way!  I am still learning cucumber so
> any advice is welcome!
> ;-)
>   

While the above code is clever I would discourage its use.  IMO, it 
looks like you are trying too hard to phrase your scenarios all within a 
single scenario outline.  In this case I would not use tables but I 
would have separate scenarios.  For example:

  Feature: user signup

  Scenario: success
    Given I am on the signup page

    When I enter valid registration information
    And I press "Register"

    Then I should see "You have signed up successfully!"

  Scenario: duplicate user with email # dunno, what really qualifies as duplicate for you...
    Given I am on the signup page
    And a user with email "foo at bar.com" exists
    
    When I enter valid registration information    
    And I fill in "Email" with "foo at bar.com"
    And I press "Register"

    Then I should see "A user has already signed up with foo at bar.com"



Does that make sense?  Basically, whenever you feel the need to embed a conditional in your scenario it means you need a separate one.  You can sometimes accomplish this by using scenario tables but that constrains you to the same setup steps.  In your case you wanted additional context for one of your scenarios in the table... this means that you probably should have a whole new scenario like above.  Your current solution obfuscates the additional context and therefore looses some of the documentation value that Cucumber offers.

FWIW.

Oh, and please try not to top-post in the future - it makes threads hard to follow. :)


-Ben



>
> On Apr 28, 11:28 am, Ben Mabey <b... at benmabey.com> 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-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
>   



More information about the rspec-users mailing list