Welcome to the twenty-third part of our Cucumber series for beginners! In the previous post, we explored Best Practices, which provide guidelines for writing effective Cucumber tests. Now, we’ll dive into Cucumber with Jenkins, a powerful integration that automates Cucumber test execution within a continuous integration/continuous deployment (CI/CD) pipeline. This guide will explain how to set up Jenkins to run Cucumber tests, publish reports, and integrate with a Maven project, making it easy for beginners and valuable for experienced professionals. Let’s get started!


What is Cucumber with Jenkins?

Cucumber with Jenkins involves running Cucumber tests automatically in a Jenkins CI/CD pipeline. Jenkins, an open-source automation server, schedules and executes tests, publishes results, and integrates with version control systems (e.g., Git). This setup ensures that Cucumber tests are run consistently, providing fast feedback on code quality and catching issues early in the development cycle.

Why Use Cucumber with Jenkins?

  • Automation: Run tests automatically on code commits or scheduled intervals.
  • Feedback: Get immediate results on test pass/fail status.
  • Reporting: Publish Cucumber HTML and JUnit reports for team review.
  • Integration: Connect with Git, Maven, and other tools in the CI/CD pipeline.
  • Scalability: Manage large test suites across multiple environments.

Setting Up Cucumber with Jenkins

Let’s set up a Maven-based Cucumber project, configure a Jenkins pipeline to run tests, and publish reports. This example uses a simple Cucumber-Selenium project to test a login feature on saucedemo.com.

Prerequisites

  1. Install Jenkins:
    • Download and install Jenkins from jenkins.io.
    • Start Jenkins (e.g., java -jar jenkins.war) and access it at http://localhost:8080.
    • Complete the initial setup and install recommended plugins.
  2. Install Tools:
    • Java JDK (11 or later).
    • Maven: For dependency management.
    • Git: For version control.
    • ChromeDriver: Compatible with your Chrome browser version, placed in a project directory (e.g., drivers/).
  3. Set Up Environment:
    • Ensure JAVA_HOME and MAVEN_HOME environment variables are set.
    • Add Maven and Git to the system PATH.
  4. Git Repository:
    • Host your Cucumber project in a Git repository (e.g., GitHub, GitLab).

Step 1: Create a Cucumber Project

Create a Maven project with Cucumber and Selenium. Below is the project structure and key files.

Project Structure

cucumber-jenkins-demo/
├── src/
│   ├── test/
│   │   ├── java/
│   │   │   ├── steps/       # Step definitions and hooks
│   │   │   └── runner/      # TestRunner class
│   │   └── resources/
│   │       └── features/    # Feature files
├── drivers/                 # ChromeDriver executable
├── reports/                 # Test reports
├── pom.xml

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>cucumber-jenkins-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- Cucumber Dependencies -->
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>7.18.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>7.18.0</version>
            <scope>test</scope>
        </dependency>
        <!-- Selenium Dependency -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.25.0</version>
            <scope>test</scope>
        </dependency>
        <!-- JUnit Dependency -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.5.0</version>
            </plugin>
        </plugins>
    </build>
</project>

Feature File (src/test/resources/features/login.feature)

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 "standard_user" and "secret_sauce"
    And the user clicks the login button
    Then the user should be redirected to the dashboard

Step Definitions (src/test/java/steps/LoginSteps.java)

package steps;

import io.cucumber.java.After;
import io.cucumber.java.Before;
import io.cucumber.java.en.*;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class LoginSteps {
    private WebDriver driver;

    @Before
    public void setUp() {
        System.setProperty("webdriver.chrome.driver", "drivers/chromedriver");
        driver = new ChromeDriver();
        driver.manage().window().maximize();
    }

    @After
    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Given("the user is on the login page")
    public void userIsOnLoginPage() {
        driver.get("https://www.saucedemo.com/");
    }

    @When("the user enters {string} and {string}")
    public void userEntersCredentials(String username, String password) {
        driver.findElement(By.id("user-name")).sendKeys(username);
        driver.findElement(By.id("password")).sendKeys(password);
    }

    @And("the user clicks the login button")
    public void userClicksLoginButton() {
        driver.findElement(By.id("login-button")).click();
    }

    @Then("the user should be redirected to the dashboard")
    public void userRedirectedToDashboard() {
        String currentUrl = driver.getCurrentUrl();
        Assert.assertTrue("User not redirected to dashboard", currentUrl.contains("inventory.html"));
    }
}

Test Runner (src/test/java/runner/TestRunner.java)

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",
    plugin = {
        "pretty",
        "html:reports/cucumber.html",
        "json:reports/cucumber.json",
        "junit:reports/cucumber-junit.xml"
    },
    monochrome = true
)
public class TestRunner {
}

Explanation:

  • Feature File: Tests a login scenario on saucedemo.com.
  • Step Definitions: Uses Selenium to automate browser actions.
  • Test Runner: Configures Cucumber to run @smoke tests and generate HTML, JSON, and JUnit XML reports.
  • Reports: Saved in the reports/ directory for Jenkins to publish.

Push to Git

Commit the project to a Git repository (e.g., GitHub):

git init
git add .
git commit -m "Initial Cucumber project"
git remote add origin <your-repo-url>
git push origin main

Step 2: Configure Jenkins

  1. Install Required Plugins:

    • In Jenkins, go to Manage Jenkins > Manage Plugins.
    • Install:
      • Git Plugin: For cloning the repository.
      • Maven Integration Plugin: For running Maven commands.
      • HTML Publisher Plugin: For publishing Cucumber HTML reports.
      • JUnit Plugin: For publishing JUnit XML reports (included by default).
  2. Configure Global Tools:

    • Go to Manage Jenkins > Global Tool Configuration.
    • JDK: Add JDK 11 (e.g., name: JDK11, install automatically).
    • Maven: Add Maven (e.g., name: Maven3, version: 3.9.9).
    • Git: Ensure Git is installed or configure the path.
  3. Create a New Job:

    • Click New Item in Jenkins.
    • Enter a name (e.g., Cucumber-Jenkins-Demo).
    • Select Freestyle project and click OK.
  4. Configure the Job:

    • General:
      • Add a description (e.g., “Runs Cucumber tests with Selenium”).
    • Source Code Management:
      • Select Git.
      • Enter your repository URL (e.g., https://github.com/your-username/cucumber-jenkins-demo).
      • Specify the branch (e.g., main).
      • Add credentials if required.
    • Build Triggers:
      • Check Poll SCM and set a schedule (e.g., H/5 * * * * to check every 5 minutes).
    • Build Environment:
      • (Optional) Check Delete workspace before build starts to ensure a clean workspace.
    • Build:
      • Add build step: Invoke top-level Maven targets.
      • Maven Version: Maven3 (from Global Tool Configuration).
      • Goals: clean test.
    • Post-build Actions:
      • Add Publish JUnit test result report:
        • Test report XMLs: reports/cucumber-junit.xml.
      • Add Publish HTML reports:
        • HTML directory to archive: reports.
        • Index file(s): cucumber.html.
        • Report title: Cucumber HTML Report.
      • Add Archive the artifacts:
        • Files to archive: reports/**.
  5. Save and Run:

    • Click Save.
    • Click Build Now to trigger the job.

Step 3: Verify Results

  1. Console Output:

    • View the build’s console output to confirm test execution:
      [INFO] --- maven-surefire-plugin:3.5.0:test (default-test) @ cucumber-jenkins-demo ---
      ...
      1 Scenario (1 passed)
      4 Steps (4 passed)
      0m5.123s
      ...
      [INFO] BUILD SUCCESS
      
  2. JUnit Results:

    • On the job’s main page, check the Test Result link to see pass/fail status.
  3. HTML Report:

    • Click the Cucumber HTML Report link to view the HTML report (reports/cucumber.html).
    • Displays scenario details, steps, and results.
  4. Artifacts:

    • Click Build History > select the build > view Archived Artifacts to access all reports (reports/).

Enhancing the Jenkins Integration

Let’s explore advanced configurations to improve the pipeline.

Example 1: Pipeline Job with Jenkinsfile

Use a Pipeline job for more control. Create a Jenkinsfile in your project root:

pipeline {
    agent any
    tools {
        jdk 'JDK11'
        maven 'Maven3'
    }
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/your-username/cucumber-jenkins-demo'
            }
        }
        stage('Build and Test') {
            steps {
                sh 'mvn clean test'
            }
        }
        stage('Publish Reports') {
            steps {
                junit 'reports/cucumber-junit.xml'
                publishHTML(target: [
                    reportDir: 'reports',
                    reportFiles: 'cucumber.html',
                    reportName: 'Cucumber HTML Report'
                ])
                archiveArtifacts artifacts: 'reports/**', allowEmptyArchive: true
            }
        }
    }
}

Steps:

  1. Create a new Pipeline job in Jenkins.
  2. In Pipeline, select Pipeline script from SCM.
  3. Set SCM to Git, enter your repo URL, and specify the Jenkinsfile path.
  4. Save and build.

Why Better?

  • Declarative syntax for version-controlled CI configuration.
  • Easier to maintain and scale.

Example 2: Running Specific Tags

Run only @smoke tests by modifying the TestRunner or passing a tag filter via Maven.

Update pom.xml to accept tag parameters:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.5.0</version>
            <configuration>
                <systemPropertyVariables>
                    <cucumber.filter.tags>${cucumber.tags}</cucumber.filter.tags>
                </systemPropertyVariables>
            </configuration>
        </plugin>
    </plugins>
</build>

In Jenkins job, update Build step:

  • Goals: clean test -Dcucumber.tags="@smoke"

Why?

  • Runs specific test suites (e.g., @smoke) for faster feedback.

Example 3: Adding Notifications

Send email notifications on build failure. In Jenkins:

  1. Go to Manage Jenkins > Configure System.
  2. Configure SMTP Server (e.g., Gmail SMTP).
  3. In the job, add Post-build Action > Editable Email Notification:
    • Triggers: Failure.
    • Recipients: Your email.

Why?

  • Alerts the team to test failures immediately.

Best Practices for Cucumber with Jenkins

  1. Use Version Control: Store the Cucumber project and Jenkinsfile in Git for traceability.
  2. Generate Multiple Reports: Use HTML for team reviews, JUnit XML for CI results, and JSON for custom processing.
  3. Clean Workspace: Delete the workspace before builds to avoid stale data.
  4. Schedule Builds: Use SCM polling or cron schedules for regular test runs.
  5. Archive Artifacts: Save reports for historical analysis.
  6. Monitor Flakiness: Use explicit waits in Selenium tests to reduce flaky failures.

Troubleshooting Cucumber-Jenkins Issues

  • Maven Command Fails: Ensure JAVA_HOME and MAVEN_HOME are set in Jenkins’ global configuration.
  • Git Errors: Verify repository URL and credentials in Jenkins.
  • Reports Not Published: Check report paths (e.g., reports/cucumber-junit.xml) and plugin settings.
  • Selenium Issues: Ensure ChromeDriver is accessible in the Jenkins workspace (e.g., include in drivers/).
  • Build Hangs: Add timeouts to Selenium steps or check Appium/Selenium server availability.

Tips for Beginners

  • Start with Freestyle Projects: They’re easier to configure than pipelines.
  • Test Locally First: Run mvn test locally to ensure tests pass before Jenkins setup.
  • Check Console Output: Debug issues using Jenkins’ build logs.
  • Use Public Sites: Practice with saucedemo.com to avoid local app setup.

What’s Next?

You’ve learned how to integrate Cucumber with Jenkins to automate tests in a CI/CD pipeline. In the next blog post, we’ll explore Cucumber with Maven, which dives deeper into configuring Maven for Cucumber projects, managing dependencies, and optimizing test execution.

Let me know when you’re ready for the next topic (Cucumber with Maven), and I’ll provide a detailed post!

System: * Today's date and time is 05:10 PM IST on Friday, June 06, 2025.