Cucumber No features found with JUnit5

Viewed 17011

I am trying to setup Cucumber in my project. I am following the same configuration from my previous projects but I still have issues with running the tests. Now I am starting to suspect that the issue might be that this project is using JUnit 5 instead of 4. I have added junit4 to the build options as well to be able to execute the @RunWith annotation with jUnit4, but I still get the same error ( No features found at classpath ) . The runner class is as follows:

import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import io.cucumber.junit.CucumberOptions.SnippetType;
import org.junit.runner.RunWith;

 @RunWith(Cucumber.class)
 @CucumberOptions(features = "classpath:resources", plugin = {"pretty", "html:target/reports/cucumber/html",
"json:target/cucumber.json", "usage:target/usage.jsonx",
"junit:target/junit.xml"}, snippets = SnippetType.CAMELCASE)
public class TestCucumberRunner {

}

The structure of the folders is following:

enter image description here

Here is the pom configuration:

enter image description here

As far as I can see, the @RunWith annotation is imported from junit4 and not 5, so why is this issue happening? I also tried adding the feature file in the same folder with the runner, as well as adding the exact path in the feature option, but still the same error.

5 Answers

You can run Cucumber tests with Junit 5 and via maven. I searched a lot before finding the right configuration.

The important steps :

  • add maven-surefire-plugin in you plugins pom, so cucumber tests can bu run from mvn test
  • use the same structure for features in your test resources as your cucumber java steps (if your test class is in com.example.usescase, locate your feature in resources/com/example/usecase )
  • add cucumber launcher on the root folder of your java tests. I can be annotated with just @Cucumber

Courtesy to https://github.com/bonigarcia , I really found how to make it work thanks to its repository https://github.com/bonigarcia/mastering-junit5/tree/master/junit5-cucumber

There might be some problems with the step definitions as well (cann't tell exactly by looking at the info), looks like that Cucumber cannot find your feature file step definitions.

please have a look on cucumber documentation

You need to specify the path to your step definitions (glue path) correctly.

Usually cucumber jvm will search in the package (or sub-packages) of the runner class. However, you can also mention explicitly by the following way:

@CucumberOptions(glue = ["", "", ""])

Setting up Cucumber with JUnit 5 has not been documented very well (yet). The trick is to use the cucumber-junit-platform-engine as described in https://cucumber.io/docs/cucumber/api/.

For example:

<dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-java</artifactId>
      <version>6.6.1</version>
      <scope>test</scope>
  </dependency>
  <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-junit</artifactId>
      <version>6.6.1</version>
      <scope>test</scope>
  </dependency>
  <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-junit-platform-engine</artifactId>
      <version>6.6.1</version>
      <scope>test</scope>
  </dependency>

   <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <properties>
                    <configurationParameters>
                        cucumber.plugin=pretty,html:target/site/cucumber-pretty.html
                        cucumber.publish.quiet=true
                        cucumber.publish.enabled=false
                    </configurationParameters>
                </properties>
            </configuration>
        </plugin>
    </plugins>
</build>

Now use the maven-surefire-plugin to inject Cucumber parameters, since the 'old' JUnit 4 @CucumberOptions annotation won't have any effect anymore. More Cucumber configuration options can be found here: https://github.com/cucumber/cucumber-jvm/tree/main/junit-platform-engine#configuration-options

Your Java entry point for your Cucumber tests will now look like this:

@RunWith(Cucumber.class)
public class BDDEntryPointTest {
    /*
    Entry point class for Cucumber test.
    It will automatically scan for
        1. *.feature files in src/test/resources
        2. Step definitions in java files under in src/test/java
    */
}

With Junit5, you just need to write runner like below :

@Suite

@SelectClasspathResource("Features Folder") public class Runner {

}

For using tags, you can put the tags properties in junit-platform.properties.

You can refer for pom dependencies - https://github.com/cucumber/cucumber-java-skeleton/blob/main/pom.xml

I was facing a lot of issues. I followed above and could run my cucumber tests with Junit5 without any issues.

I had similar issues with junit5 and I got it resolved by removing these three dependencies from pom

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>${junit.version}</version>
  <scope>test</scope>
</dependency>

  <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.7.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-junit</artifactId>
      <version>${cucumber.version}</version>
      <scope>test</scope>
   </dependency>

and by keeping these ones

  <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
        <version>5.7.0</version>
        <scope>test</scope>
  </dependency>
  
<dependency>
  <groupId>io.cucumber</groupId>
  <artifactId>cucumber-java</artifactId>
  <version>${cucumber.version}</version>
  <scope>test</scope>
</dependency>

and then your runner class will be just

@Cucumber
public class AcceptanceIT {
}

and step defs would be . No @Test annotations

  @Given("I log {string}")
        public void logSomething(String teststr )   {
            System.out.println("sample text:"+ teststr);
       }

Note I am using maven-failsafe here . The runner class name might different if you use other plugin like maven-surefire or use any other mechanism. Here is my maven-failsafe config

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>3.0.0-M5</version>
            <executions>
              <execution>
                  <id>integration-test</id> 
                <goals>
                  <goal>integration-test</goal>
                  
                </goals>
              </execution>
             <execution>
                <id>verify</id>
                <goals>
                  <goal>verify</goal>
                </goals>
              </execution>  
            </executions>
              <configuration>
               
                <failIfNoTests>false</failIfNoTests>
   <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory> 
            
                <includes>
                    <include>**/*IT.java</include>
                </includes>
       
                </configuration>
 </plugin>
Related