serenity-bdd / serenity-cucumber

Cucumber integration for the Serenity BDD Reporting library
Other
78 stars 74 forks source link

Serenity Cucumber does not recognise JUnit Test Rules #22

Open johndeverall opened 8 years ago

johndeverall commented 8 years ago

Serenity does not seem to recognise JUnit Test Rules. It does however recognise JUnit TestClass Rules. This is because Cucumber does not support JUnit TestRules for philosophical reasons. The Cucumber project does have their own spring integration, which theoretically should be usable in place of something like SpringMethodRule JUnit TestRule. However Cucumber's Spring Integration does not seem to work when Guice is on the classpath, which is a critical dependency of serenity-core.

See https://github.com/serenity-bdd/serenity-core/issues/221 for more info.

wakaleo commented 8 years ago

Cucumber-JVM can only support one type of dependency injection at a time, which makes some things tricky. What problem are you trying to solve exactly?

johndeverall commented 8 years ago

I'm trying to integration test a REST API with gherkin / jbehave or cucumber. I've got the following four components.

My test code is annotated so as to start up my api service and an in memory database before and after each test run. The below works fine.


@SpringApplicationConfiguration(ApiApplication.class)
@WebIntegrationTest("server.port=0")
@RunWith(SerenityRunner.class)
@Narrative(text = { "I want to be able to do some stuff so that I can achieve some things" })
public class ApiEndpointTests {

    // The following two rules are a replacement for @RunWith(JUnit4ClassRunner)
    // and for the Serenity spring test rules from Spring 4.2.0 onwards.
    @Rule
    public final SpringMethodRule SPRING_METHOD_RULE = new SpringMethodRule();
    @ClassRule
    public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();

    // This is the port we're running our integration tests on
    @Value("${local.server.port}")
    private int port;

    @Steps
    private SomeSteps someSteps;

    @Steps
    SomeOtherSteps someOtherSteps;

    @Before
    public void setApiPort() {
        APIClientContext.getInstance().setBaseUrl("http://localhost:" + port);
    }

    @Test
    @Title("A guy can do some stuff and then achieve some things")
    public void myTest() {
    }
}

What I'm trying to do

I've not found how to integrate gherkin stories into this using cucumber or jbehave, which is what I'm trying to do. The best I've been able to do is awkwardly compose some Given, When, Then statements using @Step annotations and log my given, when then statements to the console as part of my tests and step classes - just to keep the BDD thinking going.

Where I got to thinking about the issue

I think the programmatic issue is that I can only have one @RunWith annotation, and this is used for SerenityRunner.class. None of the other serenity runner classes (jbehave or cucumber) recognise the Rules required to jumpstart the services. They only recognise @RunWith which is used up by Serenity and so not available for Spring.

JUnit5 may have a solution with @ExtendWith, as @ExtendWith replaces @RunWith, and multiple @ExtendWith annotations are supported. However it seems further work on all sides is required so that @ExtendWith can be implemented as an alternative to @RunWith for all projects.

Is there another way to do what I'm trying to do that I've missed?

YamStranger commented 8 years ago

Hello @johndeverall .

Unfortunately I don't know any other way to do what you want.

May be @wakaleo have some ideas.