I've been battling this issue for 2 days, but out of options I guess. I'm not a guru in Cucumber or Gradle, but since my area of expertise is close (Java/Spring/Maven), I've been working on updating multiple Gradle-based Cucumber projects to the latest versions of used frameworks. One of the issues I faced was io.cucumber.core.backend.CucumberBackendException: Please annotate a glue class with some context configuration.
I resolved it by adding one such class per each of my projects like this:
@CucumberContextConfiguration
@ContextConfiguration("classpath:cucumber.xml")
public class CucumberSpringConfiguration
{
}
These configs were added to the same packages where step definitions reside, otherwise it was not visible since step definitions are specified via glue
property of @CucumberOptions
annotation in the test runner.
So it all worked in those projects until I started combining those together as dependencies. Imagine this: project A has some step definitions with its CucumberSpringConfiguration
class defined. Project B has its own step definitions with its own CucumberSpringConfiguration
class defined in the same package as its step definitions. Now project C imports A and B as its dependencies to leverage step definitions for an end to end test. And here the problem occurs:
io.cucumber.core.backend.CucumberBackendException: Glue class class com.projectA.core.stepdef.CucumberSpringConfiguration and class com.projectB.core.stepdef.CucumberSpringConfiguration are both (meta-)annotated with @CucumberContextConfiguration.
Please ensure only one class configures the spring context
What would be a way to resolve this? I thought about excluding those from the classpath like this (in build.gradle), but it did not work out:
tasks.withType(Test) {
excludes = ['**/CucumberSpringConfiguration**']
doFirst {
// Get the current classpath
def classpath = sourceSets.test.runtimeClasspath
// Filter out the specific class file I want to exclude
classpath = classpath.filter { file ->
!file.absolutePath.contains("CucumberSpringConfiguration")
}
// Set the modified classpath
setClasspath(files(classpath))
}
}
I tried to move that CucumberSpringConfiguration in dependency projects out of that step definitions package, but since it's used in glue
parameter of @CucumberOptions
annotation in the test runner, it complains about necessity of having one.
Help from Cucumber/Gradle gurus is much needed here! Thank you very much in advance!
Project A, B and C each need a runner class and a class annotated with @CucumberContextConfiguration
on the glue path. But they should not share those classes with other projects.
Because you are making a library, the production code kept in src/main
is shared but not the test code kept in src/test
. So the glue code goes into src/main
, and the runner and annotated class into src/test
.