1

I might be a little bit light on the mechanism of how Cucumber works with Spring, but my current understanding is that if there's a class on the classpath with some Cucumber hook in it, the Cucumber Spring engine will add that class/bean to the Spring context. E.g.

class MySteps(val someDep: SomeDep) {
  @Before
  fun initialize() {
  }
}

Is there any way how to disable the instantiation of this class based on certain conditions, e.g. presence of SomeDep class on the classpath? I'm thinking of an analogy to @ConditionalOnClass. Ideally, I would expect that this annotation would work out of the box but apparently it isn't.

The use case is that MySteps is in a common company-wide Cucumber library (which I can modify) and it makes sense precisely for the apps that have SomeDep on the classpath.

1 Answer 1

0

Cucumber discovers steps on the "glue path". This usually defaults the entirely class path. The glue path is a list of package names in which Cucumber should look for step definitions, hooks, ect.

If you're using Cucumber with JUnit 5, you'd configure it like through the cucumber.glue property:

import org.junit.platform.suite.api.ConfigurationParameter;
import org.junit.platform.suite.api.IncludeEngines;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;

import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;

@Suite
@IncludeEngines("cucumber")
@SelectPackages("io.cucumber.skeleton")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "io.cucumber.skeleton")
public class RunCucumberTest {
}

There are no other mechanisms by which you can control which step definitions are available.

Note that people have tried to make common libraries of steps in the past. Most notably Aslak himself and it didn't make for good Gherkin.

Instead consider sharing only the API. If sufficiently rich, the step definitions should be an extremely thin wrapper. There will be some duplication, but that duplication also provides flexibility.

This flexibility allows people writing and implementing the tests to use expressive context sensitive language. From a maintenance perspective it is also easier to evolve an API in Java than a set of company wide step definitions in Gherkin. And on top of that you can use the API for other tests as well.

For your API you may still want to do something in Spring prior to each Scenario though. For this you can use Springs [Test execution listeners][2]. cucumber-spring integrates with Spring TestContextManager so that should mostly work as expected.

Should you want to activate some manually, you can use the @CucumberContextConfiguration annotation.

@CucumberContextConfiguration
@TestExecutionListeners(...your test execution listeners)
@SpringBootTest
public class CucumberSpringConfiguration {

}
Sign up to request clarification or add additional context in comments.

6 Comments

So you are saying that if there are multiple step classes in a package and I want to disable only one of them then there's no way for me to achieve that (because the glue property works on a package level)?
Also, I don't understand what do you mean by "Instead consider sharing only the API". The MySteps class of course contains (apart from the init block) the step definitions written in Java (marked by the @When annotation). Not sure how I should split this further.
Yes. That is correct. There is no other way. And to share an API I mean for example if your scenario uses a rest API somewhere, share the Java client and DTOs for that API, not the step definitions using that client. If your application needs a specific way to be stopped/started, share the code that can be used to do this. Not the step definitions that do this.
Perhaps it helps to ask yourself, "How would I share this code to be reused in JUnit test".
"How would I share this code to be reused in JUnit test". Apparently the authors of our shared steps-lib didn't ask this question because the steps are closely coupled with cucumber (World, etc.). Honestly, I don't expect that the situation is much different in other large cucumber libraries...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.