How To Work With Cucumber Hooks

May 15, 2020 | 5 Minute Read

Tags: Cucumber , QA

Prerequisites

To set up all required tools refer to this blog.

Why Cucumber Hooks?

Hooks are blocks of code that run before or after each scenario in the Cucumber execution cycle. This allows us to manage the code workflow better and helps to reduce code redundancy. 

Hooks can be defined anywhere in the project or step definition layers using the methods @Before and @After. They are typically used for setup and tear-down of the environment before and after each scenario.

@Before - Before hooks run before the first step of each scenario. This is commonly used for prerequisite steps that need to be performed before the actual test scenario. For example, this can be as follows.

1. Initialize a web driver: This is the most common use case. We need to initialize the driver once before launching the test.

  // Define driver

  WebDriver driver;

2. Establish DB connections: Application may require access to test data at the start of the test. A couple of examples could be -

  > read data through any external sources like DB.

3. To set up test data: Application may require to access test data at the start of the test. A couple of examples could be -

  > read date from the property file

  > read data through any external sources like DB, XL, JSON, etc.

4. To set browser cookies: Certain times, the application requires to set some cookies to achieve the functional goal.

5. Navigate to default page: Whenever a test is launched, it may need to navigate to the default application URL.

 driver.get("<<APP URL >> /admin");

Annotated method style:

@Before

public void setup() {

// Do something before each scenario

}

@After - After hooks run after the last step of each scenario, even when steps are failed, undefined, pending, or skipped. This is commonly used for steps that need to be performed after the actual scenario gets executed. For example, this can be as follows.

1. Quit the web driver: This is most commonly used. After each test, we are supposed to kill the browser in order to make tests independent.

//Quit driver

driver.quit();

2. To close DB connections: If we have established the DB connection at the beginning of the test, then it is advisable to terminate at the end of the tests.

3. To clear the test data/browser cookies: As @After hook will execute at the end of each test, we have clean up activity here.

4. Sign out from the application: Signing out from the application is really essential in order to make tests independent.

5. Take screenshots for fail/pass scenarios: In order to make sure the test runs correctly, We always need to take a screenshot in case of any failure.

Annotated method style:

@After

public void teardown(Scenario scenario) {

// Do something after each scenario

}

Run Hooks with Single Scenario

  • Hooks execute before and after scenario.

BaseClass.java

login.feature

LoginSteps.java

Hook.java

Note: 

  • It is not recommended to have too many print statements in the Automation code as it slows down the execution. Here it has been added just for the explanation purpose.
  • It’s always recommended to place the chrome driver in the project folder itself. For that, create a lib folder in the project and place the chrome driver file in the folder. The project structure will look like below.
    Cucumber Hooks - Project Explorer

Execution

To execute the above code, right-click login.feature file → Run As → Cucumber Feature. On executing the login.feature file it will show below output in the console. Here I have executed with Chrome. To know more about how to execute in the different browser refer blog

Output

Cucumber Hooks - Output - Single Scenario

You can also refer to this small recording

Video file

Run Hooks with Multiple Scenarios

  • As stated earlier, Scenario Hooks execute before and after every scenario. In the below example, both the Before and After hooks are executed two times for two scenarios.

Execution Order

Cucumber Hooks - Multiple Scenarios - Execution Order

login.feature

Output

Cucumber Hooks - Output - Multiple Scenario

How to set the Priority of Cucumber Hooks?

  • Priority in Cucumber is almost the same as a priority in TestNG
  • Cucumber executes Hooks in a certain order but there is a way to change the order of the execution according to the need for the test.
  • @Before(order = int): This runs in increment order, means value 0 would run first and 1 would be after 0
  • @After(order = int): This runs in decrements order, which means the opposite of @Before. Value 1 would run first and 0 would be after 1.

Hook.java

Output

Cucumber Hooks - Output - Priority Hooks

The execution order of Hooks

Cucumber Hooks - Priority Hooks - Execution Order
  • The above diagram explains the order of execution.
  • Execution order will be Before Hook 0 -> Before Hook 1 -> Scenario ->  After Hook 1 -> After Hook 0.
  • Before the first step of each scenario, Before hooks will be run. Execution order is the same order of which they are registered. After the last step of each scenario, After hooks will be run. It doesn't matter even when there are failing, undefined, pending or skipped steps.

Tagged Hooks

In the above topic explained how hooks are executed before or after each scenario. Tagged hooks are almost similar but the only difference is that they are executed before and after the specified tag. 

If we have different prerequisites for different scenarios then we need to have different hooks for different scenarios. Let’s say we have two different tags smoke and regression and we want to perform different operations based on the tag then such things can be achieved through tagged hooks.

In the below feature file, two scenarios are tagged with @Smoke and one tagged with @Regression 

login.feature

Sometimes there could be common pre or post steps. In such cases, we can combine them in hooks. If two methods are tagged with the same tag, it will be executed alphabetically. 

Hook.java

TestRunner.java

Output

Cucumber Hooks - Output - Tagged Hooks