4

I'm using Java and Cucumber. I need to do some actions after every scenario outline. I know there are @Before and @After hooks, but they are applicable to every scenario in Scenario Outline. Is there any possibility to launch some actions exactly after all scenarios in outline and not after every scenario?

Example:

   Scenario Outline: Some scenario
   Given given actions
   When when actions
   Then display <value>
Examples:
|value|
|a    |
|b    |

I want to make execution in following way:

@Before actions

a value

b value

@After actions

@Before actions

//another scenario outline output

@After actions

Solarsoul
  • 43
  • 1
  • 1
  • 6
  • Possible duplicate of [setUp and tearDown for Scenrio outline (cucumber-jvm)](https://stackoverflow.com/questions/26911834/setup-and-teardown-for-scenrio-outline-cucumber-jvm) – Shant Dashjian Apr 27 '18 at 14:33
  • The scenario outlines are essentially scenarios, but written using different syntax. Considering that scenarios (or each example in a scenario outline) should be independent, what is the reason you need to do something after all scenario outlines have run? – Marit Aug 14 '20 at 15:06

3 Answers3

3

Yes, you can use Tags.

   @tag1
   Scenario Outline: Some scenario
   Given given actions
   When when actions
   Then display <value>
Examples:
|value|
|a    |
|b    |

Here we have specified tag1 as a tag.

Now in step definition, you can use something like this:

@Before("@tag1")
public void testSetup(){
    ...
} 

@After("@tag1")
public void testEnd(){
    ...
} 

These @before and @after are specific to tag1 now.' I hope this helps.

GaurZilla
  • 371
  • 4
  • 13
  • 1
    Both the before and after hooks will run for each scenario in the scenario outline. With the tag it is restricted to run only for that scenario outline. – Grasshopper Apr 27 '18 at 15:49
  • this didnt work for me....it still runs the hook after each scenaro in the Scenario Outline...I only want the hook to run after the Scenario Outline is complete – Tim Boland Jul 17 '23 at 17:28
1

One of the reasons this is difficult and not supported by Cucumber is because it is a really bad idea. Good testing practice stipulates that you start from a clean slate before you run each test. If you link tests together like you are doing then when something goes wrong you have to work out whether the test has failed, or something in the previous tests has caused a problem. This quickly becomes a tremendous PITA.

TLDR don't do this you will live to regret it ;)

diabolist
  • 3,990
  • 1
  • 11
  • 15
0

One way of doing this is to make use of the BeforeClass and AfterClass methods of either junit or testng for the runner. The problem is there can be only one scenariooutline in the feature file and it will need a unique runner class for it.


Having a method run only for the first scenario run off a scenario outline is pretty easy. Create a before hook to run once only using a static flag. Modify the Before hook to run for certain tags etc..

private static boolean skipFlag = false;

@Before
public void beforeHook() {

    if(!skipFlag) {
        do stuff
        skipFlag=true;
    }
}

Though this works well with one scenario outline in a feature file. Else you will need to replicate flags fro each scenariooutline. For parallel running it may get messy.


A better but a little complex solution which requires to split the examples table into 3 and give the top and bottom part tags.

@AftBef
Scenario Outline:
When User Selects <Origin>, <Destination>

@StartIt
Examples:
    | Origin        | Destination        |
    | London        | New York           |

Examples:
    | Origin        | Destination        |
    | Munich        | Moscow             |
    | Rome          | Shanghai           |

@EndIt
Examples:
    | Origin        | Destination        |
    | Miami         | San Francisco      |

Add the below hook methods with tags. You can also add tag(s) to the middle part if there is any custom logic.

@Before(value={"@StartIt"})
public void startItAll() {

    System.out.println("-----START IT BIRTH BIRTH----");
}

@After(value={"@EndIt"})
public void endItAll() {

    System.out.println("-----END IT DIE DIE---------");
}

If you have only one example just add both tags to the examples like below.

 @StartIt @EndIt
    Examples:

Need to be careful in creating the table to make sure only one example row is present for the @StartIt and @EndIt tags.

Grasshopper
  • 8,908
  • 2
  • 17
  • 32