Search code examples
javajunitcucumberintegration-testingcucumber-java

Using JUnit Hooks with Cucumber CLI Runner


I'm trying to run Cucumber's feature files in parallel using Cucumber's CLI Runner and I'm currently stuck trying to figure out how to make JUnit @BeforeClass hook to work with the CLI Runner.

At the moment, my working Runner class looks like this:

@RunWith(Cucumber.class)
@CucumberOptions(
    plugin = {
      "pretty",
      "html:target/reports/basic/report.html",
      "json:target/reports/cluecumber/cucumber.json",
      "timeline:target/reports/timeline"
    },
    tags = "@RegressionTests",
    snippets = SnippetType.CAMELCASE,
    stepNotifications = true,
    features = "classpath:features",
    glue = "my.steps.package")
public class RegressionTestsIT {

  @BeforeClass
  public static void setup() {
    ContextHolder.setupTestContext();
  }
}

And my CLI command looks like this:

java -cp "target/test-jar-with-dependencies.jar" io.cucumber.core.cli.Main -p "pretty" -p "html:target/reports/basic/report.html" -p "json:target/reports/cluecumber/cucumber.json" -p "timeline:target/reports/timeline" --threads 10 -g "my.steps.package" target/test-classes/features

What happens is that I get a NullPointerException at the tests because TestContext was not properly set up as the hook was not executed.

I tried to include both the Runner's package and the Runner class itself as glue and it didn't work.

Also tried to make my Runner extend io.cucumber.core.cli.Main and then execute my Runner in the CLI and not surprisingly it did not work either, sadly still getting NPE.

Although this issue is related to the CLI Runner use, I'm content with any answer that might help me run multiple feature files in parallel whatever the method.


Solution

  • Using JUnit Rules

    Cucumber supports JUnit's @ClassRule, @BeforeClass, and @AfterClass annotations. These will be executed before and after all scenarios. Using these is not recommended as it limits portability between different runners; they may not execute correctly when using the command line, IntelliJ IDEA, or Cucumber-Eclipse. Instead it is recommended to use Cucumber's hooks.

    When using the CLI, JUnit is not involved at all so you can not use any of JUnit annotations. However since Cucumber v7 you can use @BeforeAll and @AfterAll to declare methods that executed before and after all scenarios.

    package io.cucumber.example;
    
    import io.cucumber.java.AfterAll;
    import io.cucumber.java.BeforeAll;
    
    public class StepDefinitions {
    
        @BeforeAll
        public static void beforeAll() {
            // Runs before all scenarios
        }
    
        @AfterAll
        public static void afterAll() {
            // Runs after all scenarios
        }
    }