DEV Community

Cover image for Java + Cucumber + Generator: Automating Step Definition Creation
uttesh
uttesh

Posted on

Java + Cucumber + Generator: Automating Step Definition Creation

This is an advanced automation approach for generating step definitions in Java using Cucumber. Let's generate step classes using the Mustache templates and Gradle tasks to simplify and streamline the creation of step definition classes for your Cucumber feature files. This approach is for developers who want to eliminate boilerplate code and focus on building robust test automation frameworks.

Introduction to Cucumber and Java

Cucumber is a popular testing tool that bridges the gap between technical and non-technical teams. It uses Behavior-Driven Development (BDD) principles to define application behaviour in plain English. However, writing step definition classes for each feature file can become repetitive and time-consuming.

Why Automate Step Definitions?

Image description

Manual creation of step definitions:

  • Requires developers to repetitively translate feature file scenarios into methods.
  • Can lead to errors or inconsistencies in naming and structure.
  • Slows down the development process for large-scale projects.

Automating this process:

  • Saves time by generating classes dynamically.
  • Ensures consistency across all step definitions.
  • Makes the framework scalable and maintainable.

Step-by-Step Explanation

Step 1: Parse the Feature File

The first step involves reading the feature file and extracting scenarios and steps. Each scenario is broken down into:

  • Scenario title
  • Steps (Given, When, Then, etc.)
private static List<ScenarioData> parseFeatureFile(String featureFilePath) throws IOException {
    List<ScenarioData> scenarios = new ArrayList<>();
    List<String> currentSteps = new ArrayList<>();
    String currentScenario = null;

    try (BufferedReader reader = new BufferedReader(new FileReader(featureFilePath))) {
        String line;
        while ((line = reader.readLine()) != null) {
            line = line.trim();
            if (line.startsWith("Scenario:")) {
                if (currentScenario != null) {
                    scenarios.add(new ScenarioData(currentScenario, new ArrayList<>(currentSteps)));
                    currentSteps.clear();
                }
                currentScenario = line.substring("Scenario:".length()).trim();
            } else if (line.matches("^(Given|When|Then|And|But) .+")) {
                currentSteps.add(line);
            }
        }
        if (currentScenario != null) {
            scenarios.add(new ScenarioData(currentScenario, currentSteps));
        }
    }
    return scenarios;
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Use Mustache Template for Class Generation

With scenarios extracted, each scenario is used to generate a corresponding Java class. Mustache templates define how each class and its methods are structured.

Template Example (StepDefinition.mustache):

package {{packageName}};

import io.cucumber.java.en.*;

public class {{className}} {

{{#methods}}
    @{{stepType}}("^{{stepText}}$")
    public void {{methodName}}() {
        // TODO: Implement step: {{stepText}}
    }
{{/methods}}
}

Enter fullscreen mode Exit fullscreen mode

Step 3: Generate Java Classes

Each scenario is passed through the Mustache template, and the output is saved as a .java file in the designated directory.

Code Snippet:

private static void generateStepDefinition(ScenarioData scenario, String outputFilePath, String className) throws IOException {
    List<Map<String, String>> methods = extractStepDefinitions(scenario.getSteps());
    Map<String, Object> templateData = new HashMap<>();
    templateData.put("packageName", "com.example.steps");
    templateData.put("className", className);
    templateData.put("methods", methods);

    String templateFile = "src/main/resources/templates/StepDefinition.mustache";
    renderTemplate(templateFile, outputFilePath, templateData);
}

Enter fullscreen mode Exit fullscreen mode

Step 4: Automate the Process with Gradle

Integrate the generator into your Gradle build process to automate step definition creation. A Gradle task is defined to invoke the generator with feature file paths.

Gradle Task:

tasks.register("generateStepDefinitions", JavaExec) {
    group = "custom"
    description = "Generates step definition classes from feature files."
    mainClass = "com.example.CucumberStepGenerator"
    classpath = sourceSets.main.runtimeClasspath
    args = [
        "src/test/resources/features/sample.feature",
        "src/test/java/com/example/steps"
    ]
}

Enter fullscreen mode Exit fullscreen mode

Benefits of Using a Generator

  • Time-Saving: Reduces manual effort in creating step definitions.
  • Consistency: Ensures uniform formatting and naming conventions.
  • Scalability: Easily adapts to large projects with multiple feature files.
  • Customizability: Modify templates to match your specific requirements.

Source Code Github: https://github.com/uttesh/cucumber-step-generator

Image description

Conclusion
By combining Cucumber, Java, and Mustache templates, you can revolutionize the way step definitions are generated in your projects. This approach is a game-changer for teams working with BDD frameworks, enabling them to focus on test logic rather than repetitive setup tasks.

Stay tuned for more advanced topics on test automation!

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay