Integration Tests with Cucumber-jvm, Selenium and Maven

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/java and src/it/resources folders: 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 stop goal.

We can now execute the tests by running:

 mvn clean verify -Pintegration-tests

The -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.

Summary

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,
  • Add src/it/java as a test source folder,
  • Create your feature file,
  • Implement the step definitions,
  • Add the failsafe plugin,
  • 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!

 
---

Comment

  1. Hi… neat post…

    Do you happen to have the complete pom.xml file somewhere? It would be nice to be able to see the whole thing…

    Jason · 2012-05-08 01:15 · #

  2. No need…

    Turns out the cucumber-jvm java example has it all..

    https://github.com/tychobrailleur/cucumber-jvm-examples/blob/master/java-example/pom.xml

    Jason · 2012-05-08 04:07 · #

  3. Exactly, as mentioned in the post, the full example can be found there: https://github.com/tychobrailleur/cucumber-jvm-examples/tree/master/java-example

    sebastien · 2012-05-10 11:20 · #

  4. Wow, great article! I just began my foray into using Cucumber-jvm and Selenium and this is exactly what I needed. Thanks!

    BenC · 2012-05-16 15:19 · #

  5. Great tutorial!

    One suggestion:

    Rename LoadPageIT.java to RunCukesTest.java. The current name gives the impression that this class is somehow related to the “Page Loading” feature and only runs that one. In fact it’s not – if you add a new .feature file named Bacon next to the current one, your LoadPageIT class would run that too.

    RunCukesTest is for the entire project.

    Aslak Hellesoy · 2012-09-06 10:11 · #

  6. Hi! I have downloaded the example project from https://github.com/tychobrailleur/cucumber-jvm-examples/tree/master/java-example. When I run mvn clean verify -Pintegration-tests in the terminal I have success build, but I can’t see which steps failed and which did not. I get used to see green or red steps in the terminal while running cucumber tests. So, what should I do to display colored steps in the terminal? Thanks

    Iluha · 2012-09-06 11:30 · #

  7. @Aslak: I have now renamed the test to `RunCukesIT` as per your advice (it must still be suffixed with IT to be picked up by failsafe for integration tests). Thanks a mil for the feedback.

    @Iluha: The next installment of this series shows how to use system properties to override properties (http://www.weblogism.com/item/337/cucumber-jvm-and-maven-ii). Use the `—format pretty` option to get colours on the command line with maven.

    sebastien · 2012-09-09 20:32 · #

  8. Nice example. Could you explain please how it is possible to get properties values defined different for every profile. For example, I’d like to vary host name and other properties which are different depending on the environment (profile). Hot to get them in a Java class. System.getProperty(String key) works only for system properties if I’m right. Thank you.

    Javix · 2012-09-20 12:30 · #

  9. Nice example. Can you give another example on how to use a data table or xml string in feature and refer to it in the step definitions in java?

    Sudeshna · 2012-11-07 11:52 · #

  10. hi,
    i’m new to cucumber,we have copied the example given by github and tried in eclipse but we are not getting the how to execute the feature using mvn test,can anyone pls help me to execute

    shilpashree p n · 2014-01-06 06:29 · #

  11. Can anyone please tell me how to apply object model in this example, I tried but not able to understand.

    kailash · 2014-04-04 05:50 · #

  12. Hi Ya,
    I took sample project from github and when trying to run it using maven, I get the below result in console: can you help

    [INFO]
    [INFO] ————————————————————————————————————
    [INFO] Building Cucumber-jvm Java Example 1.0.3-SNAPSHOT
    [INFO] ————————————————————————————————————
    [INFO]
    [INFO] —- build-helper-maven-plugin:1.8:add-test-source (add-source) @ java-example —-
    [INFO] Test Source directory: C:\Auto Framework_Krish\Cucumber-jvm Java Example\src\it\java added.
    [INFO]
    [INFO] —- build-helper-maven-plugin:1.8:add-test-resource (add-resource) @ java-example —-
    [INFO]
    [INFO] —- maven-resources-plugin:2.5:resources (default-resources) @ java-example —-
    [debug] execute contextualize
    [INFO] Using ‘UTF-8’ encoding to copy filtered resources.
    [INFO] skip non existing resourceDirectory C:\Auto Framework_Krish\Cucumber-jvm Java Example\src\main\resources
    [INFO]
    [INFO] —- maven-compiler-plugin:3.1:compile (default-compile) @ java-example —-
    [INFO] Nothing to compile – all classes are up to date
    [INFO]
    [INFO] —- maven-resources-plugin:2.5:testResources (default-testResources) @ java-example —-
    [debug] execute contextualize
    [INFO] Using ‘UTF-8’ encoding to copy filtered resources.
    [INFO] skip non existing resourceDirectory C:\Auto Framework_Krish\Cucumber-jvm Java Example\src\test\resources
    [INFO] Copying 1 resource
    [INFO]
    [INFO] —- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ java-example —-
    [INFO] Nothing to compile – all classes are up to date
    [INFO]
    [INFO] —- maven-surefire-plugin:2.16:test (default-test) @ java-example —-
    [INFO] Tests are skipped.
    [INFO]
    [INFO] —- maven-war-plugin:2.1.1:war (default-war) @ java-example —-
    [INFO] Packaging webapp
    [INFO] Assembling webapp [java-example] in [C:\Auto Framework_Krish\Cucumber-jvm Java Example\target\cuke-jvm-example]
    [INFO] Processing war project
    [INFO] Webapp assembled in [18 msecs]
    [INFO] Building war: C:\Auto Framework_Krish\Cucumber-jvm Java Example\target\cuke-jvm-example.war
    [INFO] ————————————————————————————————————
    [INFO] BUILD FAILURE
    [INFO] ————————————————————————————————————
    [INFO] Total time: 4.573s
    [INFO] Finished at: Wed Jun 04 10:51:52 BST 2014
    [INFO] Final Memory: 12M/155M
    [INFO] ————————————————————————————————————
    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.1.1:war (default-war) on project java-example: Error assembling WAR: webxml attribute is requir
    ed (or pre-existing WEB-INF/web.xml if executing in update mode) -> [Help 1]
    [ERROR]
    [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
    [ERROR] Re-run Maven using the -X switch to enable full debug logging.
    [ERROR]
    [ERROR] For more information about the errors and possible solutions, please read the following articles:
    [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

    Krish · 2014-06-04 09:54 · #

  13. Hi Krish,

    This looks like it could be an issue related to whitespaces in the path; are you able to try putting the project on a path without spaces?

    sébastien · 2014-06-04 19:18 · #

 
---