Kamil Janowski
Kamil Janowski

Reputation: 2035

How do I specify test runner in Serenity tests?

I created a serenity + JBehave + spring boot test.

The test looks as follows:

Story:

Meta:

Narrative:
As a new user, in order to efficiently use the service I first want to register to the service and then log in.
During the process I want to make sure that all validations are properly executed

Scenario: user registration
Given a user with email address '[email protected]' and password 'aaa'
When attempt to register
Then system returns an information about password being too short

Test:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestServer.class)
@WebAppConfiguration
@IntegrationTest({ "server.port=6666" })
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class UserRegistrationTest extends SerenityStory {

    private String email;

    private String password;

    @Steps
    private UserRegistrationSteps userRegistrationSteps;

    @Given("a user with email address '$email' and password '$password'")
    public void givenAUserWithEmailAndPassword(@Named("email") String email, @Named("password") String password) {
        this.email = email;
        this.password = password;
    }

    @When("attempt to register")
    public void attemptToRegister() {
        userRegistrationSteps.openRegistrationPage();

        userRegistrationSteps.enterRegistrationCredentials(email, password);
    }

    @Then("system returns an information about password being too short")
    public void thenSystemReturnsAnInformationAboutPasswordBeingTooShort() {
        userRegistrationSteps.makeSureRegistrationErrorsContainErrorAboutShortPassword();
    }
}

When I run the test separately everything goes smoothly. First spring boot server starts, it generates some temporary in-memory database and only then the test is executed. If you run the test separately from the other however, the report is not generated. In order to generate reports I need to execute

gradle test aggregate

unfortunately, when I do that serenity forgets that I have the @RunWith(SpringJUnit4ClassRunner.class) annotation at all. It tries to run the test on the server that doesn't yet exist and as a result the test fails.

Here's also my build.gradle

buildscript {
    ext {
        springBootVersion = '1.2.5.RELEASE'
    }
    repositories {
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("net.serenity-bdd:serenity-gradle-plugin:1.0.59")
    }
}

group 'fi.achivi.server'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'net.serenity-bdd.aggregator'

jar {
    baseName = 'achivi'
    version = '0.0.1-SNAPSHOT'
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

gradle.startParameter.continueOnFailure = true

repositories {
    mavenCentral()
    jcenter()
}

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-thymeleaf', // all spring MVC and spring boot in one dependency
            'org.springframework.boot:spring-boot-starter-data-mongodb',

            'commons-validator:commons-validator:1.4.1', // utils
            'org.apache.commons:commons-lang3:3.4',

            'org.springframework.security:spring-security-web:4.0.1.RELEASE', //spring security
            'org.springframework.security:spring-security-config:4.0.1.RELEASE'

    testCompile 'org.springframework.boot:spring-boot-starter-test',

                'cz.jirutka.spring:embedmongo-spring:1.3.1', //mongodb dependencies
                'de.flapdoodle.embed:de.flapdoodle.embed.mongo:1.48.0',

                'net.serenity-bdd:core:1.0.47', // JBehave and serenity stuff
                'net.serenity-bdd:serenity-junit:1.0.47',
                'net.serenity-bdd:serenity-rest-assured:1.0.59',
                'org.assertj:assertj-core:1.7.0',
                'org.slf4j:slf4j-simple:1.7.7',
                'net.serenity-bdd:serenity-jbehave:1.0.23'

}


task wrapper(type: Wrapper) {
    gradleVersion = '2.3'
}

so how do I make serenity take the @RunWith annotation into account when generating reports, so that my server for the tests is actually generated?

Upvotes: 1

Views: 3121

Answers (1)

John Deverall
John Deverall

Reputation: 6280

I think you might need to use some kind of SerenityRunner instead of SpringJunit4TestRunner. However this is a little difficult. I've been trying this myself and where I have got to is below.

For some history, you could start with chapter 16 in the Serenity reference documentation.

Integrating with Spring

Although out of date, I think it is mostly applicable, and you could use the updated classes, which you'll find in their source code:

@Rule private final SpringIntegrationMethodRule springIntegrationMethodRule = new SpringIntegrationMethodRule();

and

@ClassRule private static final SpringIntegrationClassRule springIntegrationClassRule = new SpringIntegrationClassRule();

Some more up-to-date information is available about these Serenity rules in the commit for this feature.

In addition to that, if you're on Spring 4.2.0 or later, the Spring team have actually released a couple of Rules themselves, to be used as an alternative to their SpringJUnit4ClassRunner. This is probably the best option if you're on a recent version of Spring.

Here is an excellent explanation of how to use the new rules from the Spring team.

Update: I haven't actually managed to get this working myself with the above information - at least with Serenity / Cucumber so I have raised an issue with the Serenity project here. I've also asked this follow on question on stackoverflow.

Upvotes: 2

Related Questions