Cucumber and JUnit 5 are widely used testing frameworks. Integration both was cumbersome in the past, however the new cucumber-junit-platform-engine simplifies this a lot. The following post describes how that looks like using Gradle.

Cucumber

Gherkin based feature files describe the functionality of a system in a domain specific language. They should use the same words a team uses to discuss a feature.

Feature: Guess the word

    Scenario: Maker starts a game
        Given the game is setup
        When the Maker starts a game
        Then the Maker waits for a Breaker to join

Each scenario describes a series of steps which start with keywords like Given, When, and Then. In order to execute those steps, you have to write some glue code:

package your.own.steps;

import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;

public class YourSteps {

    @Given("the game is setup")
    public void setup() {
        // execute step
    }

    @When("the Maker starts a game")
    public void someStep() {
        // execute step
    }

    @Then("the Maker waits for a Breaker to join")
    public void otherStep() {
        // execute other step
    }

}

In order to run test scenarios, both feature files and glue code is necessary. In order to learn more about Cucumber, take a look at the following post.

JUnit 5

One of the biggest strengths of JUnit 5 compared to its predecessor is its extensibility. The Cucumber team used that extensibility in order to allow their platform-engine to work with the junit-platform-suite to discover feature files and glue code, as well as delegating test execution to JUnit. All you need are a few more dependencies and an additional class annotated with @Suite as well as @SelectClasspathResource in order to finalize your setup.

package your.own;

import org.junit.platform.suite.api.SelectClasspathResource;
import org.junit.platform.suite.api.Suite;

@Suite
@SelectClasspathResource("features")
public class RunCucumberTest {
}

Gradle

We are using Gradle in order to declare all required dependencies and configure how we want to run our tests. The following example shows a minimal example written in Kotlin that is capable of running Cucumber scenarios.

plugins {
    java
}

dependencies {
    testImplementation("io.cucumber:cucumber-java:latest.release") {
        because("we want to use Cucumber JVM")
    }
    testImplementation("io.cucumber:cucumber-junit-platform-engine:latest.release") {
        because("we want to use Cucumber with JUnit 5")
    }
    testImplementation("org.junit.platform:junit-platform-suite:latest.release") {
        because("we want to use the JUnit 5 @Suite annotation to select/run Cucumber tests")
    }
    testImplementation("org.junit.jupiter:junit-jupiter-api:latest.release") {
        because("we want to use JUnit 5 assertions")
    }
}

tasks {
    test {
        systemProperties(project.gradle.startParameter.systemPropertiesArgs)
        useJUnitPlatform {
            excludeTags("disabled")
            includeTags("!ignore")
        }
    }
}

Once the setup is complete, call gradle test to test your scenarios. The code example shows how to pass properties to your test, e.g. to enable parallel execution or to include/exclude certain scenarios.

In order to get started quickly, take a look at the example repository at https://github.com/cronn/cucumber-junit5-example.