Java Cucumber: Take @CucumberOptions from external source like a property file
Asked Answered
W

6

6

Is it possible to take cucumber option values from a java .properties file?

In this SO post, it shows that it is being passed from CLI.

Here's my sample class:

@RunWith(Cucumber.class)
@CucumberOptions(
        features = {"resources/features/"},
        glue = {"classpath:com/"},
        tags = {"@foo, @bar"}
)
public class UITestRunner {

}

Instead of hardcoding the tags here, I'd like to take it from a property file. Any help is appreciated!

Windbroken answered 14/7, 2017 at 5:48 Comment(3)
This feature is not implemented in Cucumber.Karlotte
Thanks! Would appreciate if you can give a link to a documentation that backs this information up.Windbroken
I think I was mistaken, please check my answer. I misunderstood your question, thought that you are asking if you can provide property file instead of feature file. Sorry, 2:00 am :). Please see my answer, it does not fit into comments.Karlotte
K
8

Cucumber will initially look for arguments provided by cucumber.api.cli.Main or @CucumberOptions

But you can override them providing (in this particular order):

  1. The OS environment variable CUCUMBER_OPTIONS
  2. The Java system property cucumber.options
  3. The Java resource bundle cucumber.properties with a cucumber.options property

Once one of described above options is found, it will be used. Overrides are provided in a variable (or property) called cucumber.options or CUCUMBER_OPTIONS. All values, except plugin arguments will override values provided by cucumber.api.cli.Main or @CucumberOptions. Plugin option will add up to the plugins specified by cucumber.api.cli.Main or @CucumberOptions.

Karlotte answered 14/7, 2017 at 6:15 Comment(4)
You can find in Cucumber Java Book. I believe official documentation is not well done (unfortunately).Karlotte
@Karlotte i want to execute cucumber tests using TestNGRunner, i have a GUI where the user select tagName and i would like to be able to change the CucumberOptions, now I'm using maven to run but I don't enjoy it - cannot stop the execution/cannot see all the logs. Unfortunately CucumberOptions accept only constants and I cannot read the options from external files or GUI.Southard
So you want to change Cucucmber options at runtime?Karlotte
Just to be clear, to enable an additional plugin at runtime: -Dcucumber.options="--add-plugin com.example.MyPlugin". To override all the compiletime plugins at runtime: -Dcucumber.options="--plugin com.example.MyPlugin"Ashaashamed
B
6

Hope you are aware that if running from the command line, you can use system properties

mvn test -Dcucumber.options="--features resources/features/ --tags ~@ignore" -Dtest=AnimalsTest

Which means that you can programmatically set these properties:

@RunWith(Cucumber.class)
public class CatsRunner {   

    @BeforeClass
    public static void before() {
        System.setProperty("cucumber.options", "--features resources/features/ --tags ~@ignore");
    }

}

Hope that gives you some ideas. For example, you can manually read the properties from a file and then achieve what you want.

Edit: apparently the above does not work. So here's my next idea, implement your own JUnit Cucumber runner by extending the Cucumber class. Refer to this for an example. So in the constructor you should have full control.

Billfish answered 14/7, 2017 at 6:2 Comment(4)
I'll give this a go. Until then please give me some time to accept this as a correct answer. Thanks for the help! PS - I have my tests in src/main/ and I'm actually building it into an executable jar so mvn test won't really be suitable for me. In any case, this insight is helpful!Windbroken
@Windbroken no worries :) I'm pretty sure this is do-able. in my open-source project [ github.com/intuit/karate ] I've been able to hack Cucumber into all kinds of things it was not designed to do. setting a system property before the cucumber runtime has been initialized is the trick. if you get stuck, let me know.Billfish
I'm sorry man this solution is not working. Can't accept this answer. When I try to run my runner class it does not even go in the @BeforeClass method. Hence I'm already getting a No features found at [classpath:.... error.Windbroken
""Passing command-line options via the property cucumber.options has been deprecated in favour of explicitly using property names. """Monopolist
R
2

I solved this by extending the Cucumber runner. You can find examples here:

For cucumber-jvm 4.0.0: https://github.com/martinschneider/yasew/blob/master/src/main/java/io/github/martinschneider/yasew/junit/YasewRunner.java

For cucumber-jvm 2.4.0: https://github.com/martinschneider/yasew/blob/db8cd74281139c14603e9ae05548530a7aebbade/src/main/java/io/github/martinschneider/yasew/junit/YasewRunner.java

The key part, as discussed in some of the replies and comments, is to set the cucumber.options system property:

String cucumberOptions =
        "--tags @"
            + getProperty(PLATFORM_KEY, DEFAULT_PLATFORM)
            + " --glue io.github.martinschneider.yasew.steps --glue "
            + getProperty(STEPS_PACKAGE_KEY)
            + " --plugin pretty --plugin html:report --plugin json:"
            + getProperty(CUCUMBER_REPORT_DIRECTORY_KEY, 
DEFAULT_CUCUMBER_REPORT_DIRECTORY)
            + "/cucumber.json"
            + " "
            + getProperty(FEATURES_DIRECTORY_KEY);
    LOG.info("Setting cucumber options ({}) to {}", CUCUMBER_OPTIONS_KEY, cucumberOptions);
    System.setProperty(CUCUMBER_OPTIONS_KEY, cucumberOptions);

I'm using a setup with Spring and JUnit and I'm not sure if there's a better place to put this code.

Overwriting the runner is not very elegant but it works like a charm!

Rasorial answered 5/10, 2018 at 10:7 Comment(1)
And what is CUCUMBER_OPTIONS_KEY?Southard
F
0

An example for an override feature source line in cucumber.properties file in project tree is:

cucumber.options=-g StepDefs src\\test\\resources\\Testfeature.feature

The Cucumber for Java Book is cool. I got it after reading this post. I experimented some time to see what path the CucumberOptions property accepts... so here above is the quick solve. ;)

StepDefs is the folder where my step definitions are located in the project tree.

I prefer this way to have everything in one place. Maybe for porting the testsuite to another system it is more common to set a System variable in the target system so the possible customer has always one directory where to place feature-files.

Fray answered 21/11, 2019 at 8:42 Comment(0)
F
0

I was searching for a solution how to pass(over write) feature file path glue (steps) path in command line in Dcucumber options. It was quite challenging and I was unable to find the exact solution in many of the forums. Finally found a working solution

Just posting here it could help anybody.

gradle -Dcucumber.options="-g XX.XXX.XXX.steps --tags @xxxxxx featurefilepath/features/" test

You must follow this order having -g as a first option. Thaanks

Fabi answered 9/8, 2020 at 17:7 Comment(0)
K
-1

I am doing like this:-

cucmberOption.properties

#cucumber.options=--plugin html:output/cucumber-html-report 
#src/test/resources
cucumber.options.feature =src/test/resources
cucumber.options.report.html=--plugin html:output/cucumber-html-report
  1. Java Class: CreateCucumberOptions.java

    Method to load properties file:-

    private static void loadPropertiesFile(){
        InputStream input = null;
        try{
            String filename = "cucumberOptions.properties";
            input = CreateCucumberOptions.class.getClassLoader().getResourceAsStream(filename);
            if(input==null){
                LOGGER.error("Sorry, unable to find " + filename);
                return;
            }
            prop.load(input);
        }catch(IOException e){
            e.printStackTrace();
        }finally{
            if(input!=null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
  2. method to get and set CucumberOptions

        private String createAndGetCucumberOption(){       
         StringBuilder sb = new StringBuilder();
         String featureFilesPath = 
         prop.getProperty("cucumber.options.feature");
         LOGGER.info(" featureFilesPath: " +featureFilesPath);
         String htmlOutputReport = 
          prop.getProperty("cucumber.options.report.html");
         LOGGER.info(" htmlOutputReport: " +htmlOutputReport);
         sb.append(htmlOutputReport);
         sb.append(" ");
         sb.append(featureFilesPath);
         return sb.toString();
        }
    
    
     private void setOptions(){
       String value = createAndGetCucumberOption();
       LOGGER.info(" Value: " +value);
       System.setProperty(KEY, value);
       }
    

And main method to run this:-

    public static void main(String[] args) {
        CreateCucumberOptions cucumberOptions = new CreateCucumberOptions();
        JUnitCore junitRunner = new JUnitCore();
        loadPropertiesFile();
        cucumberOptions.setOptions();
        junitRunner.run(cucumberTest.runners.RunGwMLCompareTests.class);
     }

And RunGwMLCompareTests.class is my Cucumber class

@RunWith(Cucumber.class)
@CucumberOptions(
        monochrome = true,
        tags = {"@passed"},
        glue =  "cucumberTest.steps")
public class RunGwMLCompareTests {

    public RunGwMLCompareTests(){

    }
}

So basically nopw you get set output report and feature folders through properties files and others options like glue definations java class. And to run the test cases just run your main class.

Regards, Vikram Pathania

Kreis answered 6/10, 2017 at 5:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.