I am using cucumber for ui testing written in java. I am trying to implement the cucumber plugin for rerunning failed scenarios, and created a second class to be the runner for those scenarios:
first class
#RunWith(Cucumber.class)
#CucumberOptions(
monochrome = true,
strict = true,
tags = {"#lakeisha"},
features = ".",
format = {"html:target/cucumber", "json:target/cucumber.json"},
plugin = {
"pretty", "html:target/cucumber-reports",
"json:target/cucumber.json",
"rerun:src/test/resources/rerun.txt" //Creates a text file with failed scenarios
})
public class RunCukeTestsIT extends BaseCucumberRunner {
}
second class:
#RunWith(Cucumber.class)
#CucumberOptions(
monochrome = true,
tags = {"#lakeisha"},
features = "#src/test/resources/rerun.txt", //Cucumber picks the failed scenarios from this file
format = {"html:target/cucumber", "json:target/cucumber.json"}
)
public class ReRunCukeTestsIT extends BaseCucumberRunner{
}
and i am running the tests using
mvn clean verify -Dcucumber.options=" --tags #lakeisha"
the problem is that running it through terminal doesn't seem to generate anything in the rerun.txt, but running it through IJ does. I also tried putting the plugin into Dcucumber.options portion of command, to no avail . Help much appreciated!
Related
I found another similarly titled question here, 42878832, but it didn't answer my question.
I am running Cucumber and would like to customise my TestRunner by specifying CucumberOptions. I am trying to add values to the plugin option and am following an example where it's specified a value of progress as one of the allowed values. When I run my code I don't see it producing the expected output .P- so am thinking that perhaps the version I am using today doesn't support this feature anymore. I am using Intellij (2020.2), Java (15), cucumber-java (6.8.1).
Does anyone know where the options are documented and more specifically where can I read the list of available options for the plugin option. I found this page CucumberOptions docs on the Cucumber site but it wasn't very helpful.
My TestRunner class looks like below.
#RunWith(Cucumber.class) #CucumberOptions(
features = {"cucumber/features"},
glue = {"steps"},
plugin = {"progress", "pretty", "html:Report1"},
dryRun = false,
monochrome = true
//tags = {"#P1"}
//name = {"Logo"}
) public class TestRunner { }
You can find the listed options in here
In javadoc:
look here
If you want to have an idea , how some of them works, have a look here
Here is a question that says about how to use progress
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!
Cucumber will initially look for arguments provided by cucumber.api.cli.Main or #CucumberOptions
But you can override them providing (in this particular order):
The OS environment variable CUCUMBER_OPTIONS
The Java system property cucumber.options
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.
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.
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!
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.
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
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
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 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
I have a pipeline job using Groovy script set up to run multiple tests in "parallel", but I am curious as to how to get the report(s) unified.
I am coding my Selenium tests in Java and using TestNG and Maven.
When I look at the report in target/surefire-reports, the only thing there is the "last" test ran of "suite".
How can I get a report that combines all of the tests within the Pipeline parallel job?
Example Groovy code:
node() {
try {
parallel 'exampleScripts':{
node(){
stage('ExampleScripts') {
def mvnHome
mvnHome = tool 'MAVEN_HOME'
env.JAVA_HOME = tool 'JDK-1.8'
bat(/"${mvnHome}\bin\mvn" -f "C:\workspace\Company\pom.xml" test -DsuiteXmlFile=ExampleScripts.xml -DenvironmentParam="$ENVIRONMENTPARAM" -DbrowserParam="$BROWSERPARAM" -DdebugParam="false"/)
} // end stage
} // end node
}, // end parallel
'exampleScripts2':{
node(){
stage('ExampleScripts2') {
def mvnHome
mvnHome = tool 'MAVEN_HOME'
env.JAVA_HOME = tool 'JDK-1.8'
bat(/"${mvnHome}\bin\mvn" -f "C:\workspace\Company\pom.xml" test -DsuiteXmlFile=ExampleScripts2.xml -DenvironmentParam="$ENVIRONMENTPARAM" -DbrowserParam="$BROWSERPARAM" -DdebugParam="false"/)
} // end stage
} // end node
step([$class: 'Publisher', reportFilenamePattern: 'C:/workspace/Company/target/surefire-reports/testng-results.xml'])
} // end parallel
There is a little more to this code after this in terms of emailing the test runner the result of the test and such.
This works great, other than the reporting aspect.
I prefer to use ExtentReports because it has a ExtentX server that allows to you report on multiple different test reports.
I used to use ReportNG but development on that stalled and so I don't recommend it any more. It doesn't allow you combine reports anyway.
Other than that, you could use CouchBase or similar JSON database to store test results and then generate your own report from that information.
After creating my feature file in eclipse, i run it as a Cucumber feature. i use the step definition the console gives me to create the first base of the test file
#Given("^the input is <(\\d+)> <(\\d+)>$")
these should be outputted by the console however currently it is showing the feature without the step definitions.
Feature: this is a test
this test is to test if this test works right
Scenario: test runs # src/test/resources/Test.feature:4
Given: i have a test
When: i run the test
Then: i have a working test
0 Scenarios
0 Steps
0m0,000s
this feature is just to check if cucumber is working properly.
the runner:
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
import org.junit.runner.RunWith;
#RunWith(Cucumber.class)
#CucumberOptions(
monochrome = true,
dryRun = false,
format = "pretty",
features = "src/test/resources/"
)
public class RunCukes {
}
what can be the cause of the console not showing all the info?
TL:DR console does not show the step regex for missing steps
EDIT: added feature file
Feature: this is a test
this test is to test if this test works right
Scenario: test runs
Given: i have a test
When: i run the test
Then: i have a working test
The problem is in the feature file. Using : after Given, When and Then is the problem. I was able to reproduce your issue with your feature file. But when I removed the : and ran the feature file, with the same Runner options provided above, I got the regex to implement missing step definitions.
P.S I am using IntelliJ, but don't think it would make a difference.
Feature: this is a test
this test is to test if this test works right
Scenario: test runs # src/test/resources/Test.feature:4
Given i have a test
When i run the test
Then i have a working test
Below is what I got:
Testing started at 19:12 ...
Undefined step: Given i have a test
1 Scenarios (1 undefined)
3 Steps (3 undefined)
0m0.000s
Undefined step: When i run the test
You can implement missing steps with the snippets below:
#Given("^i have a test$")
public void i_have_a_test() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
#When("^i run the test$")
public void i_run_the_test() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
#Then("^i have a working test$")
public void i_have_a_working_test() throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
Undefined step: Then i have a working test
1 scenario (0 passed)
3 steps (0 passed)
Process finished with exit code 0
it can happen if your .feature file is invalid somehow. I once had it happen just because I had two || together in the examples table of my Scenario Outline
This question already has answers here:
Run single test from a JUnit class using command-line
(4 answers)
Closed 9 years ago.
I am trying to run tests from a separate class where information can be compiled and reported. I am having difficulty running individual tests, however.
I tried:
for (int i = 0; i < testRuns; i++) {
JUnitCore.runClasses(InternetExplorerTestClass.class, MozillaFirefoxTestClass.class, GoogleChromeTestClass.class);
}
but that limits the control I have over the results and reporting the data.
How do I run a single test from a test suite? Thank you in advance.
It almost looks like you are doing something like a Selenium test? If you use Gradle as your build tool, you can easily run one specific test by using the "include" filter option like so. (You could do something similar with Ant, SBT, or Maven as well). Personally, I think using the build tool to pick the tests to run is more elegant than writing code to run certain classes.
tasks.withType(Test) {
jvmArgs '-Xms128m', '-Xmx1024m', '-XX:MaxPermSize=128m'
maxParallelForks = 4
// System properties passed to tests (if not http://localhost:8001/index.html)
systemProperties['testProtocol'] = 'http'
systemProperties['testDomain'] = 'djangofan.github.io'
systemProperties['testPort'] = 80
systemProperties['testUri'] = '/html-test-site/site'
systemProperties['hubUrl'] = 'localhost'
systemProperties['hubPort'] = '4444'
}
task runParallelTestsInFirefox(type: Test) {
description = 'Runs all JUnit test classes in parallel threads.'
include '**/TestHandleCache*.class'
testReportDir = file("${reporting.baseDir}/ParallelTestsFF")
testResultsDir = file("${buildDir}/test-results/ParallelTestsFF")
// System properties passed to tests
systemProperties['browserType'] = 'firefox'
// initial browser size and position
systemProperties['windowXPosition'] = '100'
systemProperties['windowYPosition'] = '40'
systemProperties['windowWidth'] = '400'
systemProperties['windowHeight'] = '600'
}
This is taken from a example project I wrote here.