Cucumber is a popular tool that supports Behavior Driven Development (BDD) framework. Here we define the application behavior using Gherkin language, a simple English text that is understandable by both technical and non-technical stakeholders. In the feature file, the Gherkin syntax uses Given, When and Then keywords to define the pre-conditions, actions and expected outcomes respectively.
We often come across certain actions that need to be performed repeatedly during the test execution, it could be for every scenario or step. But these actions do not fit into the essence of Background or Given statements and therefore need not be defined in the Gherkin code. These pre-actions and post-actions are usually the setup and teardown of the test environment that are not significant to the specific behavior that is being validated in the test scenario. The typical cases of setup includes,
Creating a webDriver instance.
Establishing a DB connection.
Setting up test data.
Setting up browser cookies for specific session states.
Navigating to a specific URL.
And the typical cases of teardown includes,
Quitting the webDriver session.
Closing the DB connection.
Deleting the test data.
Deleting the browser cookies.
Logging out of the application.
Taking a screenshot of test failure.
If these actions are hidden from the Gherkin code, then where do we manage them? This is where Cucumber Hooks come into play.
Hooks are blocks of code that are implemented as methods with specific annotations such as @Before and @After. They can be declared in any class but as a common practice placed in a dedicated class for better organization and reusability. During the execution of a feature file, the hooks are automatically triggered before or after each scenario or step.
Types of Cucumber Hooks
Hooks can be categorized into four types, they are:
Scenario hooks
Step hooks
Conditional hooks
Global hooks
Let's look into each type of hooks in detail.
Scenario Hooks
Scenario hooks are methods run before and after each scenario. A specific method can be annotated with “@Before” to act as a Before hook which will be executed before the first step of each scenario or it can be annotated with “@After” to act as an After hook which will be executed after the last step of each scenario. The After hook will run even if the last step is failed or skipped.
Let’s see a simple example:
Feature File
Step Definitions Class
Hooks Class
Output on Running the Feature File
From the above output, we can see that the before hook is run before the first step of each scenario and the after hook is run after the last step of each scenario. In case of scenario outline, each example is considered a separate scenario and hooks will run for each of those scenarios as shown in the above example. In the hooks methods, instead of print statements you can have any piece of code that needs to be executed.
Now what if there are multiple Before and After hooks that need to be run in specific order for each scenario? We can handle this case by using the order attribute.
@Before(order = int): This runs in increment order, where value 0 would run first and 1 would be after 0
@After(order = int): This runs in decrements order, where value 1 would run first and 0 would be after 1.
Let’s see a simple example:
Feature File with Background Step
Hooks Class
Output
Note: When background steps are defined in the feature file, the before hook runs before the first step of the background and after hooks run after the last step of the scenario.
Order of Execution of Scenario Hooks:
Step Hooks
Step hooks are run before and after each step of every scenario. Once the BeforeStep hook is executed, the AfterStep hook will also be executed even if the step fails. In case of any step getting failed, the following step and its hook will be skipped.
Let’s see a simple example:
Feature File with Background step
Hooks
Output
Note: When background steps are defined in the feature file, the step hooks will run for each step of background as well.
Order of Execution of Scenario Hooks:
Conditional Hooks
Now we know that Before and After hooks will be executed for every scenario in the feature file. But at times we will have scenarios that require a different prerequisite than others which means they need a different hook to be executed. We can achieve this by using Before and After hooks associated with tags. These hooks are not generic to every scenario rather they are specific to scenarios with certain tags
Let’s look at some examples to understand Conditional hooks with various tag expressions.
Before Hook for Scenarios tagged with @First
Let's consider the Feature File with tagged scenarios
This hook will be executed only for those scenarios tagged with @First, i.e., for scenarios 1, 4 and 5 in the feature file.
2. Before Hook for Scenarios tagged with @First and @Second
This hook will be executed only for those scenarios tagged with @First and @Second, i.e., for scenarios 4 and 5 in the feature file.
3. Before Hook for Scenarios tagged with @First or @Second
This hook will be executed only for those scenarios tagged with @First or @Second, i.e., for scenarios 1, 2, 4 and 5 in the feature file.
4. Before Hook for Scenarios tagged with @First and not @Third
This hook will be executed only for those scenarios tagged with @First but not @Third, i.e., for scenarios 1 and 4 in the feature file.
5. Multiple Before Hooks for Scenarios tagged with @First
When there are multiple tagged hooks that need to be executed in a particular order for a tagged scenario we can use order attribute.
In this case the Before hook with order 1 followed by hook with order 2 will be executed only for those scenarios tagged with @First, i.e., for scenarios 1, 4 and 5 in the feature file.
Similarly we can use After hooks with different tag expressions.
Global Hooks
Global hooks are executed only once before the first scenario or after the last scenario of the test execution lifecycle.
Let's look at an example for Global hooks with multiple feature files
The above are the feature files with two scenarios each. The below Hooks class has two methods annotated with @BeforeAll and @AfterAll expected to run only once before all scenarios and after all scenarios respectively.
Output on Running the Runner Class with Both the Feature Files
From the above output we can understand that the BeforeAll is run once before all the scenarios of all the feature files and AfterAll is run once after the completion of all the scenarios.
Understanding Cucumber hooks and implementing them effectively in your testing process can help you build an organized and robust test automation framework. Keep exploring hook strategies, and happy testing!
Kommentare