3

I Want to execute Background only once in each cucumber feature files for multiple scenarios. how can i do that in step files?

Feature: User can verify...........

Background: Given Enter test data for a specific logic

Scenario: Verify ......... 1 When A1 And B1 Then C1

Scenario: Verify ......... 2 When A2 And B2 Then C2

Scenario: Verify ......... 2 When A3 And B3 Then C3

SaeeK
  • 217
  • 1
  • 4
  • 12
  • The idea is for scenarios to be isolated from each other so that something in one scenario doesn't break a different scenario - If the background is only being called once then changes made in one scenario could affect others, and your scenario running becomes order dependent - If you are just wanting to prepopulate some tables that don't get changed by the tests then you might want to look at the :except option for DatabaseCleaner when used with :truncation – Thomas Walpole Jan 12 '16 at 23:11

7 Answers7

6

Background is designed to run each time before each scenario. Its not good and standard as well to hack Background.

ASM
  • 709
  • 2
  • 8
  • 27
5

Tests should be isolated. That is the way Cucumber is designed, and there's a very good reason for it. I would strongly urge against it unless you absolutely have to.

If you have something that needs to be executed before your entire test suite, consider a @BeforeAll hook.

That said, I've come across this before. We had tests which would start a process that took a long time (such as provisioning a VM, which would take 10 minutes a time..), but could be skipped in other tests if it had already been done.

So you may want to design steps along the lines of..

"Given that .. X has been done"

and in the step detect whether X is done or not, and if not, then do X. If it has, then skip it. For example, say creating users is a process that takes absolutely ages. Then we could do..

Given that user "Joe Bloggs" has been created

The step definition would first try to determine if Joe existed, and then if they didn't, create the user. You have an initial start up problem, but then other tests will be able to safely assume Joe exists.

WHY YOU SHOULD NOT DO THIS

If you do this, there's a high probability your tests will conflict with one another.

Say you have lots of tests that use the Joe Bloggs user. Maybe some will delete him from the system. Some might temporarily deactivate the user, add roles, change their name.. all sorts of things. All tests assume certain things about the system they're testing, and you are intentionally harming your tests assumptions about the environment.

It's particularly bad if you are running parallel tests. Maybe your system has a restriction that only one person can log in at a time as Joe. Or every test is changing loads of things about Joe, and no test can assume anything about the state of the Joe user. Then you'll be in a huge mess.

The best solution is often to create brand new data for each test you run. Open up those APIs and create disposable data for each test run. Here's a good blog post about it: https://opencredo.com/test-automation-concepts-data-aliases/

burythehammer
  • 382
  • 2
  • 6
2

If you want your background to be run only once. You can add condition with an instance variable ex, i==0 then execute the logic and increment i at the end of the method.

For the next scenario, i value is 1 which is not equal to 0,the it won't execute the logic.

Mujeeb007
  • 41
  • 1
1

We can have both scenario and scenario outline in single feature file. With this scenario will run only once and scenario outline would run based on the data given in Example table

rahul
  • 11
  • 1
0

We had similar problem and couldn't find any solution for background for multiple scenario. Background is design to run for all scenario after every scenario it will run Background. If you have examples in scenario in this case it will run after each examples.

We had to option to fix this problem.

1) Used @BeforeClass Annotation of junit 2) Create setup scenario and It will always execute in first place.

For example : In API testing, You take login once and used that session every time to access other API

Feature:Setup Data Given Customer logs in as System Admin

Scenario: Verify ......... 1 When A1 And B1 Then C1

Scenario: Verify ......... 2 When A2 And B2 Then C2

Scenario: Verify ......... 2 When A3 And B3 Then C3

After first scenario it will execute all scenario and You don't need to use background.

I would say using background every time it must be part of business requirement else it will create unwanted test data and load on testing environment and may result in slow down testing execution time.

Please let me know if you find other solution.

N..
  • 906
  • 7
  • 23
  • I am using Ruby here in my test frameworks. And i have written similar structure as you have, ran before hook only once with login steps but still i want to run background only once for each feature files. Because i don't want to load same data again and again before each scenario which takes way lot of my time. And different feature files i have different set of data to load. So my background should execute only once. – SaeeK Jan 12 '16 at 21:16
  • You could hack background using status but it is not good and Industrial standard to do. As per my knowledge there is no way to run background using cucumber – N.. Jan 12 '16 at 21:52
  • I can fix it using a work around: instead having multiple scenarios, i can keep all steps into 1 scenario and having some modification in my step codes which actually might resolve my issue. – SaeeK Jan 13 '16 at 16:47
  • All modification in scenario should make sense to Business owner and other stake holder. Fixing scenario for Automation point is not good idea. – N.. Jan 13 '16 at 17:08
0

Running some steps (Background) before each set of scenarios or a Scenario Outline can also be achieved by creating a tagged @Before method and passing a Scenario object as parameter. Within the before method, execute your logic only if the scenario name is different as compared to the last scenario.

Below is a how you can do it:

Feature:Setup Data Given Customer logs in as System Admin

@BeforeMethodName
Scenario Outline: Verify ......... 1 
    When <Variable1> And <Variable2> 
    Then <Variable3>

Examples:
    | Variable1 | Variable2 | Variable3 |
    | A1        | B1        | C1        |
    | A2        | B2        | C2        |
    | A3        | B3        | C3        |
    | A4        | B4        | C4        |


@BeforeMethodName
Scenario Outline: Verify ......... 2 
    When <Variable1> And <Variable2> 
    Then <Variable3>

Examples:
    | Variable1 | Variable2 | Variable3 |
    | X1        | Y1          | Z1      |
    | X2        | Y2          | Z2      |
    | X3        | Y3          | Z3      |
    | X4        | Y4          | Z4      |

And define the @BeforeMethodName as below:

private static String scenarioName = null;

public className BeforeMethodName(Scenario scene) {

        if(!scene.getName().equals(scenarioName)) {

//            Implement your logic

        scenarioName = scene.getName()
        }

        return this;
    }

This way BeforeMethodName will be called before each scenario but will execute the logic only once per Scenario Outline.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
-1

Old issue, but adding incase others find this.

As has been mentioned, cucumber should only be used to structure your code.

You can use tagged hooks to create items which are used on a sub-set of tests. Furthermore you could isolate the code into Helpers, and then conditionally call these helpers inside your ruby steps.

Probably need a bit more clarity to make a judgement

Luke Hill
  • 460
  • 2
  • 10