This post will show how to use cucumber-jvm and Maven to run integration tests with Selenium on a regular webapp; as you’ll see, this is more of a Maven exercise than a cucumber-jvm one, as Cucumber tests are simply executed as JUnit tests. It can be a bit tricky as it requires a bit of Maven build lifecycle knowledge1, but once you get the idea, it all makes perfect sense.
For those only interested in the example, you will find it there.
The first thing we want to do is to segregate the integration tests from the unit tests. The reason for this is that it makes it easier to locate them, but also it allows you to run them separately: this is especially important if you want run the integration tests as part of your CI build. I personally prefer to have my integration tests under
src/it/java, and suffixed with
IT, so to do this, we first create a new profile and add the maven-failsafe-plugin:
The profile will be helpful to separate the integration tests execution if you want to run only in certain situations; it can also be used to define property values specifically for integration tests.
We then create the
src/it/resources will contain the feature files, whereas
src/it/java will contain the step definitions and the JUnit test cases to be executed. We also need to add the new source folders to
the build with the build-helper-maven-plugin:
The JUnit test case is very simple:
It actually is empty: it cannot contain any method. It uses the
Cucumber JUnit runner. The
Cucumber.Options can be used to specify the format of the report created during the test, the feature files to execute, or the tags to run.
Next, the feature file is here somewhat trivial:
Finally, here are the step definitions:
As you can see, we are using the Selenium client in this step definition. We therefore need to add the dependencies to selenium (along with the cucumber-jvm ones) in our profile:
We also need to start the selenium server before the tests begin:
This plugin defines here two executions:
start-selenium-server, which is executed before the integration tests during the phase called
pre-integration-test, and calls the
start goal, and
stop-selenium-server called after the integration tests, during the
post-integration-test phase, and that calls the
stop goal of that plugin (for a reminder of the different phases of the build lifecycle, see the reference).
Finally, we configure the Jetty maven plugin to start and deploy the war we want to test:
Similarly to the selenium plugin, we start the Jetty server
pre-integration-test (by running the
run goal, and stop it
post-integration-test with the
We can now execute the tests by running:
mvn clean verify -Pintegration-tests
-P flag indicates that Maven must activate the
integration-tests profile; as the plugins and dependencies are defined in that profile, the integration tests will only be executed if you activate that profile.
All the required “services” (Jetty, Selenium) are started during the
pre-integration-test phase, and then stopped during the
post-integration-test phase. The cucumber integration tests stored in
src/it/java are executed during the
integration-test phase by running the JUnit tests that use
Cucumber.class as a runner.
To run the integration tests:
- Create a new profile,
src/it/javaas a test source folder,
- Create your feature file,
- Implement the step definitions,
- Add the
- Add the selenium server plugin,
- Add the jetty plugin.
Hope this helps!
1 Once you’ve understood the build lifecycle, you understand Maven, so most definitely a knowledge worth having!