Running a whole scenario before another scenario

1.2k views Asked by At

I'm not able to figure out how to run a whole scenario before an other scenario, so that my test are not dependant on eachother.

I have this imaginary scenarios.

Scenario A
Given I have something
When I sumbit some data
I should see it on my webpage

Scenario B
Given SCENARIO A
When I delete the data
I should not see it on my webpage

When I run this scenario case, the software does not recognize Scenario A in scenario B, and ask me to create the step, like this...

You can implement missing steps with the snippets below:

@Given("^Registrere formue og inntekt$")
public void registrere_formue_og_inntekt() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}

2

There are 2 answers

0
m4ktub On

Cucumber scenarios are supposed to be independent. A lot of work is done assuming and ensuring that independence. Trying to go against will be an obstacle course.

Having said that, you could create your custom implementation of the Cucumber JUnit runner. Having this custom implementation, and by looking at the source of the original runner, you can expose / wrap / change the internals to allow what you want. For example with the following runner:

public class MyCucumber extends Cucumber {

    private static Runtime runtime;
    private static JUnitReporter reporter;
    private static List<CucumberFeature> features;

    public MyCucumber(Class<?> clazz) throws InitializationError, IOException {
        super(clazz);
    }

    @Override
    @SuppressWarnings("static-access")
    protected Runtime createRuntime(ResourceLoader resourceLoader,
            ClassLoader classLoader, RuntimeOptions runtimeOptions)
            throws InitializationError, IOException {
        this.runtime = super.createRuntime(resourceLoader, classLoader, runtimeOptions);
        this.reporter = new JUnitReporter(runtimeOptions.reporter(classLoader), runtimeOptions.formatter(classLoader), runtimeOptions.isStrict());
        this.features = runtimeOptions.cucumberFeatures(resourceLoader);

        return this.runtime;
    }

    public static void runScenario(String name) throws Exception {
        new ExecutionUnitRunner(runtime, getScenario(name), reporter).run(new RunNotifier());
    }

    private static CucumberScenario getScenario(String name) {
        for (CucumberFeature feature : features) {
            for (CucumberTagStatement element : feature.getFeatureElements()) {
                if (! (element instanceof CucumberScenario)) {
                    continue;
                }

                CucumberScenario scenario = (CucumberScenario) element;
                if (! name.equals(scenario.getGherkinModel().getName())) {
                    continue;
                }

                return scenario;
            }
        }

        return null;
    }

}

You can setup your test suite with:

@RunWith(MyCucumber.class)
public class MyTest {
}

And create a step definition like:

@Given("^I first run scenario (.*)$")
public void i_first_run_scenario(String name) throws Throwable {
    MyCucumber.runScenario(name);
}

It is a fragile customization (can break easily with new versions of cucumber-junit) but it should work.

0
Sébastien Le Callonnec On

You could either:

  • Use a Background to group all the steps that need to be executed before the different scenarii:
Background:
Given I have something
When I submit some data
Then I should see it on my webpage 

Scenario: B
When I delete the data
Then I should not see it on my webpage 
  • Group them as part of a step definition:
@Given("^Scenario A")
public void scenario_A() {
    I_have_something();
    I_submit_some_data();
    I_should_see_it_on_my_page();
}

which you can then use like this:

Given Scenario A
When I delete the data
Then I should not see it on my webpage

Using this technique, you usually observe that some actions are constantly reused, and you may want to factor them out so that they can be reused across different step definitions; at that point, the Page Object pattern comes very handy.