5

I have a feature with a background section which takes multiple minutes; it's setting up state on a remote system via an API. I'd like to have it execute only once for all the scenarios which follow, instead of executing for every scenario. My scenarios don't change any state, they're read-only so there should be no side-effects from one scenario to another.

I'm not using rails, and don't have a local database, so can't do stuff with database transactions.

I'm currently thinking to do something with Before in env.rb and have some conditional code based on an implicit convention/meaning for tags, e.g. "@background-only-once", could make some custom code skip the steps, or it could execute different logic in the step-definitions – but it's a bit nasty to try to share this across executions.

Thoughts?

Sune Kaae
  • 51
  • 1
  • 2
  • When you say 'have it execute only once for all the scenarios which follow', does that mean scenarios in the same feature file? Do the steps in your background ever have to be re-invoked (e.g. if one of them appears in a different feature file)? – Jon M Dec 13 '11 at 11:15
  • a) yep, I'd like to have the steps in "background" section only executed once, before any of the scenarios *in that feature* are run. b) doesn't matter; it could work either way. – Sune Kaae Dec 13 '11 at 21:10
  • This is an excellent question and I'm surprised there were no acceptable answer to it. I have exactly the same issue and wander what would be the best approach to deal with it. Any suggestion/help is very appreciated. – Dragan Nikolic May 18 '16 at 18:02
  • I had this issue back in 2013 and requested something to fill this need (see https://groups.google.com/forum/#!topic/cukes/gTKZeUS_7dI). Apparently it has been requested and denied repeatedly over the course of Cucumber's life (though I stopped following it shortly after posting that). – Keith Bennett Jan 23 '19 at 04:50

2 Answers2

2

This doesn't really solve it, but here's what I do in that situation.

I go to one scenario, and just label the different "scenarios" in comments. It's exactly what would happen if you just comment the additional scenario headers out.

Here's an example of commenting out the second scenario, and running of the state of the test at the end of the first feature

Feature: Admin can manage organizations
  In order to ...

Scenario: can add
  When I log into the admin
  When I follow "Organizations"
  When I follow "Add"

  When I fill in "Email" with "red@cross.com"
  When I fill in "Name" with "Red Cross"
  When I press "Save"
  Then I should see "success"

# Scenario: can edit
  When I follow "Red Cross"
  When I fill in "Name" with "Green Cross"
  When I press "Update"

  Then I should see "success"
Josh Crews
  • 779
  • 2
  • 11
  • 21
  • perhaps I'm not sufficiently familiar with the terminology here, but don't quite understand your suggestion - hope you can clarify. In particular, don't understand your reference to "comments" or "scenario headers"... – Sune Kaae Dec 13 '11 at 21:11
  • I added an example where I comment out the Scenario header – Josh Crews Dec 22 '11 at 03:17
  • Downvoting. This basically breaks a lot of the assumptions that Cucumber makes, and also gives up test isolation. – Marnen Laibow-Koser Jul 02 '21 at 15:17
0

If you don't want your background to be executed for each scenario, then it's not a background, is it?

If you're calling remote services each time you run your Cucumber scenario, don't do that. Instead, use Webmock and VCR as described at http://marnen.github.io/webmock-presentation/webmock.html. Your tests will be faster and more accurate.

Marnen Laibow-Koser
  • 5,959
  • 1
  • 28
  • 33
  • Other testing frameworks have the functionality that OP is talking about. For instance, RSpec has before(:each) and before(:all) for this purpose (see http://stackoverflow.com/questions/16617052/rails-rspec-before-all-vs-before-each). So it seems like the question stands- does Cucumber also offer this? – Richie Thomas Apr 29 '14 at 20:45
  • @agentutah Yes, Cucumber has this functionality, but it's a bad idea for the OP's use case unless the scenarios can be *absolutely guaranteed* not to change state (which, at least 99% of the time, they can't be). Since the tests are calling remote services, they should be using Webmock and VCR to remove the network overhead. In other the words, the OP's testing approach is flawed and should be fixed. – Marnen Laibow-Koser May 05 '14 at 18:29
  • 1
    In terms of Guerkin, and what 'Background' represents, you are correct: It's not a 'Background'. However, in terms of first inspection, and readability 'Background' does look like it should run once, and since there is no alternative solution to running something once, before multiple scenarios, it's no surprise many developers are asking the same question and making the false assumption that's what 'Background' is. It may not be intention of Guerkin to provide a type of programming language either, but developers are wanting to use it like one because it makes testing so much easier. – Steve Tomlin Mar 07 '17 at 08:32
  • @SteveTomlin "there is no alternative solution to running something once, before multiple scenarios" Not true. You can use Cucumber's `Before` hooks, optionally constrained by tags. – Marnen Laibow-Koser Aug 26 '17 at 15:13
  • Yes, this can be done, but it is a hook that does not go into the feature, but instead into the code. Of course this can be resolved by providing a label \@background within the feature. There is also another consideration in that if several features were to need the same \@background label, but you only wanted your background to ever run once, and not for each feature you have to manually detect if the \@background has been run, which is possible to do, but you have to code it. It isn't integral to the idea of Background only ever running once. Maybe there should be a AllFeaturesBackground. – Steve Tomlin Sep 18 '17 at 09:25
  • @SteveTomlin Anyone with a modicum of Cucumber experience should know that Background runs before every feature that it affects. Something that runs once before all features *isn't a background*; it's a global setup hook, and the way to do that is with Before. (If you really want Gherkin in your Before block, you could use the `steps` method to run arbitrary Gherkin, but I can't imagine why you'd ever want to do that, if you're not abusing your setup hooks.) – Marnen Laibow-Koser Sep 19 '17 at 00:45