Welcome to the seventeenth part of our Cucumber series for beginners! In the previous post, we explored Cucumber Plugins, which extend Cucumber’s functionality with custom reporting and integrations. Now, we’ll dive into the Test Runner, a critical component that orchestrates the execution of Cucumber tests by tying together feature files, step definitions, and plugins. This guide will explain what a Test Runner is, how to configure it, and provide practical examples to make it easy for beginners and valuable for experienced professionals. Let’s get started!
What is a Test Runner in Cucumber?
A Test Runner is a Java class in a Cucumber project that serves as the entry point for running tests. It uses the @RunWith(Cucumber.class)
annotation to integrate with JUnit and the @CucumberOptions
annotation to configure test execution, specifying details like feature file locations, step definition packages, tags, and plugins. The Test Runner acts as a coordinator, ensuring that Cucumber executes your scenarios correctly and generates the desired reports.
Why Use a Test Runner?
- Centralized Configuration: Define all test execution settings in one place.
- Test Execution: Run feature files and step definitions seamlessly with JUnit.
- Customization: Filter tests by tags, select report formats, and enable/disable features.
- CI/CD Integration: Integrate with build tools like Maven and CI systems like Jenkins.
- Scalability: Manage large test suites with clear organization.
How a Test Runner Works
The Test Runner class is annotated with:
@RunWith(Cucumber.class)
: Tells JUnit to use Cucumber’s test runner instead of the default JUnit runner.@CucumberOptions
: Configures options like:features
: Path to feature files.glue
: Package(s) containing step definitions and hooks.tags
: Filters scenarios by tags.plugin
: Specifies report formats.monochrome
: Improves console output readability.dryRun
: Checks for undefined steps without executing tests.strict
: Fails tests if undefined or pending steps exist.
When you run the Test Runner class, Cucumber:
- Loads the feature files specified in
features
. - Matches steps to definitions in the
glue
package(s). - Executes scenarios, respecting
tags
filters. - Generates reports using the specified
plugin
options.
Creating and Configuring a Test Runner
Let’s create a feature file, step definitions, and a Test Runner to demonstrate how it orchestrates test execution. Assume you have a Cucumber project set up with Java and Maven, as described in the Installation and Setup post.
Example: Feature File
Create a file named login.feature
in src/test/resources/features
:
Feature: User Login
As a user, I want to log in to the application so that I can access my account.
@smoke
Scenario: Successful login with valid credentials
Given the user is on the login page
When the user enters "user1" and "pass123"
Then the user should be redirected to the homepage
@regression
Scenario: Failed login with invalid credentials
Given the user is on the login page
When the user enters "user1" and "wrongpass"
Then the user should see an error message
Step Definitions
Create LoginSteps.java
in src/test/java/steps
:
package steps;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
public class LoginSteps {
@Given("the user is on the login page")
public void userIsOnLoginPage() {
System.out.println("Navigating to login page");
}
@When("the user enters {string} and {string}")
public void userEntersCredentials(String username, String password) {
System.out.println("Entering username: " + username + ", password: " + password);
if (password.equals("wrongpass")) {
throw new RuntimeException("Invalid credentials");
}
}
@Then("the user should be redirected to the homepage")
public void userRedirectedToHomepage() {
System.out.println("Verifying redirection to homepage");
}
@Then("the user should see an error message")
public void userSeesErrorMessage() {
System.out.println("Verifying error message");
}
}
Create a Test Runner
Create TestRunner.java
in src/test/java/runner
:
package runner;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/test/resources/features",
glue = "steps",
tags = "@smoke or @regression",
plugin = {
"pretty",
"html:target/cucumber-reports/cucumber.html",
"json:target/cucumber-reports/cucumber.json",
"junit:target/cucumber-reports/cucumber-junit.xml"
},
monochrome = true,
dryRun = false,
strict = false
)
public class TestRunner {
}
Explanation:
- features: Points to the directory containing feature files.
- glue: Specifies the package (
steps
) containing step definitions. - tags: Runs scenarios tagged with
@smoke
or@regression
. - plugin: Generates console output (
pretty
), HTML, JSON, and JUnit XML reports. - monochrome: Ensures clean console output.
- dryRun: Set to
false
to execute tests (iftrue
, checks for undefined steps only). - strict: Set to
false
to allow undefined/pending steps (iftrue
, fails on undefined steps).
Run the Tests
Run the TestRunner
class in your IDE or use Maven:
mvn test
Output:
Feature: User Login
@smoke
Scenario: Successful login with valid credentials
Given the user is on the login page
When the user enters "user1" and "pass123"
Then the user should be redirected to the homepage
@regression
Scenario: Failed login with invalid credentials
Given the user is on the login page
When the user enters "user1" and "wrongpass"
java.lang.RuntimeException: Invalid credentials
...
Then the user should see an error message
2 Scenarios (1 passed, 1 failed)
6 Steps (4 passed, 1 failed, 1 skipped)
0m0.245s
Reports:
- HTML:
target/cucumber-reports/cucumber.html
(viewable in a browser). - JSON:
target/cucumber-reports/cucumber.json
(machine-readable). - JUnit XML:
target/cucumber-reports/cucumber-junit.xml
(CI-compatible).
Advanced Test Runner Configurations
Let’s explore advanced configurations to customize test execution.
Example 1: Running Specific Tags
Update TestRunner.java
to run only @smoke
scenarios:
@CucumberOptions(
features = "src/test/resources/features",
glue = "steps",
tags = "@smoke",
plugin = {"pretty", "html:target/cucumber-reports/smoke.html"},
monochrome = true
)
Run the tests:
mvn test
Output:
Feature: User Login
@smoke
Scenario: Successful login with valid credentials
Given the user is on the login page
When the user enters "user1" and "pass123"
Then the user should be redirected to the homepage
1 Scenarios (1 passed)
3 Steps (3 passed)
0m0.123s
The HTML report (target/cucumber-reports/smoke.html
) will only include the @smoke
scenario.
Example 2: Dry Run Mode
Set dryRun = true
to check for undefined steps without executing tests:
@CucumberOptions(
features = "src/test/resources/features",
glue = "steps",
tags = "@smoke or @regression",
plugin = {"pretty"},
monochrome = true,
dryRun = true
)
Run the tests:
mvn test
Output:
Shows steps without executing them, highlighting any undefined steps (none in this case since all steps are defined).
Example 3: Multiple Glue Packages
If step definitions and hooks are in different packages, specify multiple glue
paths:
@CucumberOptions(
features = "src/test/resources/features",
glue = {"steps", "hooks"},
tags = "@smoke or @regression",
plugin = {"pretty", "html:target/cucumber-reports/cucumber.html"},
monochrome = true
)
This is useful for projects with separate packages for steps and hooks.
Using Test Runner with CLI
You can bypass the Test Runner and run tests directly via the Cucumber CLI, specifying options similar to @CucumberOptions
:
mvn cucumber:test -Dcucumber.features=src/test/resources/features -Dcucumber.glue=steps -Dcucumber.filter.tags="@smoke or @regression" -Dcucumber.plugin=pretty,html:target/cucumber-reports/cucumber.html
However, the Test Runner is preferred for:
- Consistent configuration across team members.
- IDE integration (e.g., running tests directly in IntelliJ).
- CI/CD pipelines using Maven or Gradle.
Integrating Test Runner with CI/CD
To integrate the Test Runner with CI/CD tools like Jenkins:
- Ensure
pom.xml
includes the Cucumber and JUnit dependencies. - Configure the Test Runner with a JUnit XML plugin:
plugin = {"junit:target/cucumber-reports/cucumber-junit.xml"}
- In Jenkins, add a build step to run
mvn test
and a post-build step to publish JUnit reports (target/cucumber-reports/cucumber-junit.xml
). - Archive HTML reports as artifacts:
plugin = {"html:target/cucumber-reports/cucumber.html"}
This allows you to view test results and reports in Jenkins.
Best Practices for Test Runner
- Centralize Configuration: Keep all test settings in the Test Runner for consistency.
- Use Meaningful Tags: Filter tests with tags (e.g.,
@smoke
,@regression
) for targeted execution. - Organize Report Files: Save reports in a dedicated directory (e.g.,
target/cucumber-reports
). - Enable Monochrome: Use
monochrome = true
for clean CI logs. - Test Dry Run: Periodically use
dryRun = true
to check for undefined steps. - Keep It Simple: Avoid overly complex
glue
orplugin
configurations.
Troubleshooting Test Runner Issues
- Feature Files Not Found: Verify the
features
path is correct (e.g.,src/test/resources/features
). - Step Definitions Not Found: Ensure the
glue
package matches the step definition location (e.g.,steps
). - Tag Filters Incorrect: Check tag syntax (e.g.,
@smoke
vs.smoke
) and logical operators (and
,or
). - Reports Not Generated: Confirm
plugin
paths are writable and correctly formatted. - Test Runner Not Executing: Ensure
@RunWith(Cucumber.class)
and@CucumberOptions
are properly annotated.
Tips for Beginners
- Start with Basic Configuration: Use minimal
features
,glue
, andplugin
options initially. - Run from IDE: Test the Test Runner in your IDE (e.g., IntelliJ) for quick feedback.
- Check Console Output: Use the
pretty
plugin to verify test execution. - Experiment with Tags: Try different tag filters to understand selective execution.
What’s Next?
You’ve learned how to use the Test Runner to orchestrate Cucumber test execution and configure test settings. In the next blog post, we’ll explore Integration with Selenium, which allows you to automate web browser interactions for end-to-end testing with Cucumber.
Let me know when you’re ready for the next topic (Integration with Selenium), and I’ll provide a detailed post!
System: * Today's date and time is 04:40 PM IST on Friday, June 06, 2025.