6

We have a Spring Boot app and we want to start from within this app the execution of a Cucumber feature. Whenever the user clicks a button in the spring app, then the call comes in a class (CucumberTestService) where we start the execution of our Cucumber feature.

Here is the structure of the source code that is interesting for us:

    - src
        -main
            -com
                -bino
                    -panel
                        -server
                            -reference
                                -cucumber
                                    -steps
                                        -SendMessagesDefs.java
                                    -CucumberTestService.java

We prepare the arguments in CucumberTestService:

   String[] args = new String[]{
                "--strict",
                "--glue",
                "com.bino.panel.server.reference.cucumber.steps",
                "--plugin",
                "pretty",
                "/CUCUMBER-FEATS/" + feature + ".feature",
                "--plugin",
                "json:" + reports_path + "/cucumber-reports-" + feature + "/Cucumber.json",
                "--plugin",
                "junit:" + reports_path + "/cucumber-reports-" + feature + "/Cucumber.xml",
                "--plugin",
                "html:" + reports_path + "/cucumber-reports-" + feature,
                "--plugin",
                "usage:" + reports_path + "/cucumber-reports-" + feature + "/cucumber-usage.json",
                "--plugin",
                "pretty:" + reports_path + "/cucumber-reports-" + feature + "/cucumber-pretty.txt"
        };

then we are trying to launch it in the following way - exactly as it is launched in cucumber.api.cli.Main:

    run(args, Thread.currentThread().getContextClassLoader());

Now this works pretty fine in our IDE (Eclipse & IntelliJ), however when we pack this in a spring boot jar it stops working.

For deployment, the whole application is bundled up in one jar and has the following structure :

    - BOOT-INF
        -classes
            -com
                -bino
                    -panel
                        -server
                            -reference
                                -cucumber
                                    -steps
        -lib
    - META-INF
        MANIFEST.ML
    - org
        -springframework
            -boot
                -loader

When trying to execute it, Cucumber does not seem to be able to find the implementation that is defined in the glue parameter:

1 Scenarios (1 undefined) 7 Steps (7 undefined) 0m0.000s

We spent quite some time to investigate this issue and came down to the conclusion that the Cucumber is not able to find the classes from this path "com.bino.panel.server.reference.cucumber.steps" when executing it from a Spring Boot jar. But they are found correctly when the same code is execute from an IDE (Eclipse, IntelliJ).

Any suggestion of how can we "help" Cucumber & Spring find the glue classes within a spring boot jar?

Jar Versions used (taken from our build.gradle file):

    - compile group: 'io.cucumber', name: 'gherkin', version: '6.0.14'
    - compile(group: 'info.cukes', name: 'cucumber-java8', version: '1.2.5')
    - compile(group: 'io.cucumber', name: 'cucumber-junit', version: '4.2.6')
    - compile(group: 'io.cucumber', name: 'cucumber-picocontainer', version: '2.4.0')

Spring Boot version is 2.1.3

Any help/suggestion/ideas are highly appreciated! Many thanks!

Lavinia
  • 141
  • 7
  • Check: https://github.com/cucumber/cucumber-jvm/issues/1320#issuecomment-367503875 – M.P. Korstanje Apr 16 '19 at 14:36
  • Thanks for your reply! We do work on a Windows environment. We did check that issue, but somehow more guidance would be useful. Could it be also related to this https://github.com/cucumber/cucumber-jvm/issues/1540 ? – Lavinia Apr 16 '19 at 14:44
  • 1
    Not likely as you're loading from a spring-jar. Please read the ticket carefully. You can only access the resources in a spring-jar through `ApplicationContext`. – M.P. Korstanje Apr 16 '19 at 14:56
  • Maybe it's a side question but we realized that we are not using the latest versions of the jars (it's specified above the version of each one of them). But the cucumber-core-1.2.5.jar is released in 2016-09-12 and by now the latest release is 4.3.0; We tried to get the latest jars for all the dependencies, but that did not work - they seem to be incompatible. Is there a jar compatibility table for all the cucumber & gherkin related jars? – Lavinia Apr 16 '19 at 18:23
  • I would **strongly** recommend using maven, gradle or even appache ivy for dependency management. But if you must do it by hand you can still manually parse the pom. They're available on maven central. – M.P. Korstanje Apr 16 '19 at 18:57
  • Which JRE version are you running? – MikeJRamsey56 Apr 25 '19 at 19:03
  • We are using JDK 1.8 (1.8.0_201 to be more precise). We still couldn't find any clean solution to this problem and we ended up manually adding these 2 jars: _cucumber-core_ and _cucumber-picocontainer_ in the executable jar that Gradle builds. – Lavinia May 03 '19 at 12:26

1 Answers1

0

Using Gradle, place the Cucumber artifacts (ie features, step implementations, etc) into a subproject, eg my-cucumber-tests, separate from the Spring Boot app.

Then in the Spring Boot app's build.gradle, add:

bootJar {
  // make backend, features, and steps available to Cucumber at runtime
  requiresUnpack '**/my-cucumber-tests-*.jar', '**/cucumber-java-*.jar'
}
Noel Yap
  • 18,822
  • 21
  • 92
  • 144