/cucumber-companion

Maven & Gradle plugins providing convenient support for running Cucumber test directly from Maven/Gradle

Primary LanguageGroovyApache License 2.0Apache-2.0

License Maven Central GitHub Workflow Status

Cucumber Companion

Why would you add the Cucumber Companion plugin to your build?

Gradle and Maven (Surefire/Failsafe) support only class-based tests (gradle/#4773, SUREFIRE-1724), which means that they can’t discover cucumbers *.feature files as tests. The recommended workaround is to create a single JUnit 5 suite class to run all the feature files. This works fine, if your goal is to just always run all tests. However, if you want to be able to run a single feature file or use advanced test acceleration techniques, such as Predictive Test Selection (PTS), or Test Distribution (TD), then you need to have a single test class per feature file.

This is where the Cucumber Companion plugins come in: they automate the creation of the necessary JUnit 5 suite files to allow a fine-grained selection of tests.

We think of the generated JUnit 5 suite files as companions to the respective Cucumber feature files. Also, the plugins don’t replace anything from Cucumber, but act as companions to it. Hence, we named the plugin Cucumber Companion.

Installation and Usage

Prerequisites

This document assumes that you have followed the basic instructions from https://cucumber.io/docs/installation/java/ and https://github.com/cucumber/cucumber-jvm/tree/main/cucumber-junit-platform-engine to set up the necessary dependencies.

Gradle

The Cucumber Companion plugin requires at least Gradle version 7.3.

Add the plugin declaration to the plugins block in your build.gradle(.kts) file.

plugins {
    id("com.gradle.cucumber.companion") version "1.1.0"
}

If your Cucumber feature files are in the standard src/test/resources folder, this is all you have to do. The plugin adds a testGenerateCucumberSuiteCompanion task, which you can run manually to verify that the generation works.

Test Suites

If your build uses the JVM Test Suite Plugin, and your features are not in the default test-suite, then you can enable the companion file generation for other test suites as follows:

build.gradle.kts (Kotlin)

testing {
    suites {
        functionalTest {
            generateCucumberSuiteCompanion(project)
        }
    }
}

build.gradle (Groovy)

testing {
    suites {
        functionalTest {
            cucumberCompanion.generateCucumberSuiteCompanion(delegate)
        }
    }
}

The added companion task has the pattern of <suiteName>GenerateCucumberSuiteCompanion, so for a suite named functionalTest it would be functionalTestGenerateCucumberSuiteCompanion. However, there’s usually no need to call it manually since the compile<suiteName>Java task depends on it.

Disabling generation for the default test task/suite

If you need to disable the generation of companion files for the default test task/suite, then you can do so via the cucumberCompanion extension.

build.gradle.kts (Kotlin)

cucumberCompanion {
    enableForStandardTestTask.set(false)
}

build.gradle (Groovy)

cucumberCompanion {
    enableForStandardTestTask = false
}

Generation of companions not failing if there are no tests

This is interesting especially for test cases retries when all but few tests being filtered out. It adds failIfNoTests = false to the generated @Suite annotation. By default, companions execution will fail if all tests of a suite have been filtered out in the JUnit5 discovery phase. See also Test Retry Gradle Plugin.

build.gradle.kts (Kotlin)

cucumberCompanion {
    allowEmptySuites.set(true)
}

build.gradle (Groovy)

cucumberCompanion {
    allowEmptySuites = true
}

For the same outcome at the test suite level, define:

build.gradle.kts (Kotlin)

testing {
    suites {
        functionalTest {
            generateCucumberSuiteCompanion(project) {
                allowEmptySuites.set(true)
            }
        }
    }
}

build.gradle (Groovy)

testing {
    suites {
        functionalTest {
            cucumberCompanion.generateCucumberSuiteCompanion(delegate) {
                allowEmptySuites = true
            }
        }
    }
}

Note that the configuration of a test suite will have higher priority than plugin-level configuration.

Maven

The plugin has been tested with Maven versions >= 3.8.6.

Add this plugin declaration to your pom.xml. The goal is bound to the generate-test-sources lifecycle phase.

<build>
    <plugins>
        <plugin>
            <groupId>com.gradle.cucumber.companion</groupId>
            <artifactId>cucumber-companion-maven-plugin</artifactId>
            <version>1.1.0</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate-cucumber-companion-files</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

By default, the plugin generates *Test.java files for Surefire. If you prefer to run your tests with Failsafe instead, then you can configure the plugin to use IT as suffix instead.

<build>
    <plugins>
        <plugin>
            <groupId>com.gradle.cucumber.companion</groupId>
            <artifactId>cucumber-companion-maven-plugin</artifactId>
            <version>1.1.0</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate-cucumber-companion-files</goal>
                    </goals>
                    <configuration>
                        <generatedFileNameSuffix>IT</generatedFileNameSuffix>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Generation of companions not failing if there are no tests

This is interesting especially for test cases retries when all but few tests being filtered out. It adds failIfNoTests = false to the generated @Suite annotation. By default, companions execution will fail if all tests of a suite have been filtered out in the JUnit5 discovery phase.

<build>
    <plugins>
        <plugin>
            <groupId>com.gradle.cucumber.companion</groupId>
            <artifactId>cucumber-companion-maven-plugin</artifactId>
            <version>1.1.0</version>
            <executions>
                <execution>
                    <goals>
                        <goal>generate-cucumber-companion-files</goal>
                    </goals>
                    <configuration>
                        <allowEmptySuites>true</allowEmptySuites>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>