Issue
Just recently I got to experience scenario parallel execution with Cucumber + JUnit 5 which works fine and I intend to use from now on. Previously since I also use cucumber-spring, I've use Spring to manage a single TestContext instance as a bean annotated with @Component
which I reset every Scenario using @Before
. Now that there are more scenarios running in parallel, naturally I need a threaded solution. My idea for a solution was roughly the following:
/* Store the Current Scenario in a Thread Local */
private ThreadLocal<Scenario> currentScenario = new ThreadLocal<>();
@Before
public void setup(final Scenario scenario) {
currentScenario.set(scenario);
}
/* Get Scenario from a Context Map with ScenarioId as the key */
private Map<String, TestContext> contextMap = new HashMap<>();
public TestContext getContext(final Scenario scenario) {
return contextMap.get(scenario.getId());
}
The thing is, I don't know if the Scenario starts and end in a single thread or if this proposed solution is safe at all. Is there any other way to get access to the current Scenario's Scenario
instance? Any other solutions for this problem? Thank you very much.
Solution
If you're on a recent version of Cucumber, then your step definitions classes are scenario scoped by default and should not be annotated with @Component
.
Each scenario gets a new instance of the step definition class.
So this is safe, even with parallel execution:
private Scenario currentScenario;
@Before
public void setup(final Scenario scenario) {
currentScenario = scenario;
}
If you have other classes without step definitions that should have a unique instance in each scenario you can combine @Component
with @ScenarioScoped
.
https://github.com/cucumber/cucumber-jvm/tree/main/cucumber-spring#sharing-state-between-steps
Answered By - M.P. Korstanje
Answer Checked By - Timothy Miller (JavaFixing Admin)