Java Cucumber: Take @CucumberOptions from external source as properties file
Can cucumber option values ββbe used from java.properties file?
In this SO post, it shows that it is being passed from the 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 would like to grab it from a properties file. Any help is appreciated!
source to share
Cucumbers first look for arguments provided cucumber.api.cli.Main
or@CucumberOptions
But you can override them by providing (in this particular order):
- OS environment variable
CUCUMBER_OPTIONS
- Java system property
cucumber.options
- Java resource bundle
cucumber.properties
with propertycucumber.options
As soon as one of the above options is found, it will be used. Overrides are provided in a variable (or property) named cucumber.options
or CUCUMBER_OPTIONS
. All values ββother than plugin arguments will override the values ββsupplied by cucumber.api.cli.Main
or @CucumberOptions
. Plugin option will add to plugins specified by cucumber.api.cli.Main
or @CucumberOptions
.
source to share
Hope you know that when running from the command line you can use the system properties
mvn test -Dcucumber.options="--features resources/features/ --tags ~@ignore" -Dtest=AnimalsTest
This 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 this gives you some ideas. For example, you can manually read the properties from a file and then achieve what you want.
Edit: Obviously this doesn't work. So here is my next idea, implement your own JUnit Cucumber runner by extending the class Cucumber
. See this for an example . Therefore, you must have complete control in the constructor.
source to share
I solved this by expanding the cucumber ranch. 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/YasewR
The key part, as discussed in some of the answers and comments, is setting the system property cucumber.options
:
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 is a better place to put this code.
Runner rewriting isn't very elegant, but it works like a charm!
source to share
I do 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
-
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(); } } } }
-
method for getting and setting 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 the main method to run: -
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 you get a bunch of release reports and function folders through properties files and other parameters like the java class for defining the glue. And to run test cases, just run your main class.
Best regards, Vikram Patrania
source to share