Integration test executed by cucumber tends to leave behind context that causes problems with subsequent tests. Obvious solution appeared to be Spring's @DirtiesContext
, but instead of tearing down the context after all the cucumber features have been run, it does this after each and every scenario, thus making the test execution time rather lengthy.
Tried also with @TestExecutionListeners
, but no luck.
@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( classes = { MyApplication.class, MyTestComponent.class }, loader = SpringApplicationContextLoader.class )
@ActiveProfiles( { "test", "someotherprofile" } )
@DirtiesContext( classMode = DirtiesContext.ClassMode.AFTER_CLASS )
@WebIntegrationTest( randomPort = true )
public class StepDefs extends StepDefUtils {
// givens, whens, thens
Am I trying to use DirtiesContext in an unsupported way?
Cucumber skips all steps after a failed step by design. Once a step has failed, the test has failed and there should be no reason to perform the next steps. If you have a need to run the additional steps, likely your scenario is testing too many different things at once.
@DirtiesContext is a Spring testing annotation. It indicates the associated test or class modifies the ApplicationContext. It tells the testing framework to close and recreate the context for later tests. We can annotate a test method or an entire class.
Following are the two files required to execute a Cucumber test scenario: Features. Step Definition.
@DirtiesContext may be used as a class-level and method-level annotation within the same class or class hierarchy.
As previous answer said the scenarios get compiled and run as separate classes stopping DirtiesContext from working and there are no per feature hooks in cucumber for same reason.
Workaround is to put tags in scenarios and have a class with hook detect these and conditionally dirty the context during the afterTestClass method. The tag lets you control when context gets dirtied for example if want each feature to have fresh context then mark last scenario with tag, or can have many time per feature as and when needed.
public class CucumberFeatureDirtyContextTestExecutionListener extends AbstractTestExecutionListener{
private static boolean dirtyContext = false;
@After("@DirtyContextAfter")
public void afterDirtyContext(){
dirtyContext = true;
}
@Override public void afterTestClass(TestContext testContext) throws Exception {
if (dirtyContext) {
testContext.markApplicationContextDirty(HierarchyMode.EXHAUSTIVE);
testContext.setAttribute(DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE, TRUE);
dirtyContext = false;
}
}
}
Mark scenarios with tag
@DirtyContextAfter
Scenario: My scenario
On steps class register the listener with spring
@TestExecutionListeners(listeners = {DependencyInjectionTestExecutionListener.class, CucumberFeatureDirtyContextTestExecutionListener.class})
Make sure the listener is in cucumber glue so after hook is registerd
Could not get it working on beforeClass as the context is already set up so have to do on afterClass.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With