4

I am having a java project which is built using maven.

I have multiple packages,feature files based on different functionalities. The project test structure is as below.

src
  ->test
    ->java
      ->com
        ->usercreation
          TestStepDef.java
        ->uservalidation
          TestStepDef.java
   ->resources
        ->usercreation
           usercreation.feature
        ->uservaliation
           uservalidatin.feature

I have only one RunCukesTest.java file

@RunWith(Cucumber.class)
@CucumberOptions(format = { "html:target/cucumber-html-report",
                        "json:target/cucumber-json-report.json" }, 
                        features = "src/test/resources/",
                        glue = "??????",
                        tags = {"~@ignore"}
            )
 public class RunCukesTest {

 }

In this case it runs all my feature files. But it is not able to find my specific Step definitions for the feature. So I have to give the glue option as "com.usercreation". But if I do so when it runs the uservalidation feature file it will not be able to pick up the appropriate step definition. In my use case I don't want both the step def file to be in the same package, as they have many steps with different functionalities.

Is there a possible way where I can give the glue option dynamically based on the package name the feature file is running. Or am I missing any other approach to this project.

googytech
  • 479
  • 4
  • 7
  • 18

3 Answers3

11
glue = { "classpath:com/usercreation", "classpath:com/uservalidation" },
MikeJRamsey56
  • 2,779
  • 1
  • 20
  • 34
  • 1
    **classpath:** is src/test/java by Surefire default. – MikeJRamsey56 Apr 08 '16 at 00:43
  • Regarding the dynamic part, each time you run you specify a glue argument. You can override using **-Dcucumber.options** rather than editing your runner file enabling you to pick which step definition files to put in classpath. I don't recommend this however. Remember [KISS](https://en.wikipedia.org/wiki/KISS_principle). – MikeJRamsey56 Apr 08 '16 at 13:51
  • I tried this approach before. But one shortcoming with this approach is that in future if there is many packages that is getting added, then the glue path parameters will keep on going. – googytech Apr 10 '16 at 17:57
  • @googytech Just keep adding glue terms as you add folders under classpath:. It is what it is. Ruby cucumber handles this sort of thing better. You just place everything in folders under the support folder and/or make use of the World object. – MikeJRamsey56 Apr 11 '16 at 03:10
  • @googytech One more option is to take advantage of dependency injection to control which step definition files get wired in. You can start [here](https://cucumber.io/blog/2015/07/08/polymorphic-step-definitions). – MikeJRamsey56 Apr 12 '16 at 13:12
  • Thanks. It was really helpful – googytech Apr 13 '16 at 06:05
  • 1
    @googytech You could show your appreciation by accepting my answer ... :-) – MikeJRamsey56 Apr 13 '16 at 14:28
1

Move your RunCukesTest to a package above all the steps. Cucumber will search its classpath and find any step in the same package or a subpackage.

Setting the location as suggested by MikeJRamsey56 is another option.

Thomas Sundberg
  • 4,098
  • 3
  • 18
  • 25
0

Whilst some good alternative solutions have been provided, I haven't seen anyone answer your question directly.

Yes it is possible to dynamically change @CucumberOptions (cucumber annotation), however it require the use of Java reflection since annotations cant be parameterized.

To see an example of cucumber annotations being dynamically modified, please refer to this project: https://github.com/workpeter/ARGOS

In particular the runner class. Which as of today can be found in this location: https://github.com/workpeter/ARGOS/blob/master/src/test/java/integrationTests/cucumber/Runner.java

Peter
  • 11
  • 3