hooks in cucumber
Photo by Castorly Stock on Pexels.com

1.Overview of Hooks in Cucumber

1.1. When Should Hooks Be Used?

Hooks can be used to perform background tasks that are not part of business functionality. Such tasks could be:

  • Starting up a browser
  • Setting or clearing cookies
  • Connecting to a database
  • Checking the state of the system
  • Monitoring

A use case for monitoring would be to update a dashboard with the test progress in real-time.

Hooks are not visible in the Gherkin code. Therefore, we should not see them as a replacement for a Cucumber Background or a given step.

We’ll look at an example where we use hooks to take screenshots during test execution.

1.2. Scope of Hooks

Hooks affect every scenario. Therefore, it’s good practice to define all hooks in a dedicated configuration class.

It’s not necessary to define the same hooks in every glue code class. If we define hooks in the same class with our glue code, we’d have less readable code.

2. Hooks

Let’s first look at the individual hooks. We’ll then look at a full example where we’ll see how hooks execute when combined.

2.1. @Before

Methods annotated with @Before will execute before every scenario. In our example, we’ll start up the browser before every scenario:

@Before
public void initialization() {
    startBrowser();
}

If we annotate several methods with @Before, we can explicitly define the order in which the steps are executed:

@Before(order=2)
public void beforeScenario() {
    takeScreenshot();
}

The above method executes second, as we pass 2 as a value for the order parameter to the annotation. We can also pass 1 as a value for the order parameter of our initialization method:

@Before(order=1)
public void initialization()

So, when we execute a scenario, initialization() executes first, and beforeScenario() executes second.

2.2. @BeforeStep

Methods annotated with @BeforeStep execute before every step. Let’s use the annotation to take a screenshot before every step:

@BeforeStep
public void beforeStep() {
    takeScreenshot();
}

2.3. @AfterStep

Methods annotated with @AfterStep execute after every step:

@AfterStep
public void afterStep() {
    takeScreenshot();
}

We’ve used @AfterStep here to take a screenshot after every step. This happens regardless of whether the step finishes successfully or fails.

2.4. @After

Methods annotated with @After execute after every scenario:

@After
public void afterScenario() {
    takeScreenshot();
    closeBrowser();
}

In our example, we’ll take a final screenshot and close the browser. This happens regardless of whether the scenario finishes successfully.

2.5. The Scenario Parameter

The methods annotated with a hook annotation can accept a parameter of type Scenario:

@After
public void beforeScenario(Scenario scenario) { 
    // some code
}

The object of type Scenario contains information on the current scenario. Included are the scenario name, number of steps, names of steps, and status (pass or fail). This can be useful if we want to perform different actions for passed and failed tests.