Problem: I need to run my cucumber .feature file to execute in an order defined by me and rather not to run in the default order which is the folder structure.
I am running Appium for Android Native Apps built using cucumber .features file.
on windows machine, running on actual devices.
Now my Runcuckes file looks like below:
package runner;
import org.junit.runner.RunWith;
import org.testng.annotations.Test;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
import cucumber.api.testng.AbstractTestNGCucumberTests;
//#RunWith(Cucumber.class)
#CucumberOptions(features = { "src/test/java/features" },
glue = { "Steps" },
monochrome = true,
tags = { "#CustomerInsightsSurveyPopupGiveFeedback,"
+ "#TestAccountSceanrios"
+ "#ShortlistPage,"
+ "#SavedSearchesPage,"
+ "#SearchResultPage,"
+ "#Short,"
+ "#SuggestedSearch" })
// public class RunCucke {
public class RunCucke extends AbstractTestNGCucumberTests {
}
Running your features or scenarios in order is Cuking the WRONG way.
In all testing linking one test to another is an anti-pattern. It makes your tests fragile and difficult to debug. Each test should be independent of every other test.
In Cucumber you use Givens to setup the state of your scenario. When's to actually do something. Then's to check your results. Your scenarios Given's should include everything needed to setup your application so you can do your When.
Cucumber encourages you to run your scenarios in a random order, and to reset just about everything between each scenario. Don't work against this, you will make things much more difficult if you do.
Related
I am evaluating different load testing tools. After trying JMeter and having two exceptions when running and viewing the test result, I would like to give Gatling a spin. Reading to various resources I fail to find an idea how to execute once own Java Code.
I understand that Gatling is written in Scala but it runs on a JDK and Scala is able to incooperate/call Java code. So the question is, what does it take to combine both and if there are any resources available.
You can import and call your java class in any scala class.
So... Example:
I have scala class with gatling scenario
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import utils.NewRandom
class Example extends Simulation {
val protocol = http.baseUrl("https://httpbin.org")
val request = http("get request")
.get("/get")
val scn = scenario("Http bin scenario")
.exec(request)
before({
println(s"java random ${new NewRandom().getJavaRandom}")
})
setUp(
scn.inject(
atOnceUsers(1)
).protocols(protocol)
)
}
Gatling has before() and after() methods for execute before and after load run https://gatling.io/docs/current/general/simulation_structure/#hooks
If you pay attention on above code (in before() method) you will see the line where I create java object and call method.
Java class:
package utils;
import java.util.Random;
public class NewRandom {
public Integer getJavaRandom() {
return new Random().nextInt();
}
}
This has been puzzling me for half a day now. I can't seem to find the issue. Basically I have my Test runner, feature file, and the steps file in my workspace. The java files are in the same package (i.e. no package).
Below is my TestRunner.java
import org.junit.Test;
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
#RunWith(Cucumber.class)
#CucumberOptions(features = "test/resources/features", tags = { "~#Ignore" })
public class TestRunner {
#Test
public void feature() {
}
}
My feature file, helloWorld.feature
Feature: Simple Test Feature
Scenario: Run Scenario ONE
GIVEN step one
WHEN step two
THEN step three
and my steps file CucumberJava.java,
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class CucumberJava {
#Given("^step one$")
public void step_one() {
System.out.println("step one");
}
#When("step two")
public void step_two() {
System.out.println("step two");
}
#Then("^step three$")
public void step_three() {
System.out.println("step three");
}
}
When I execute TestRunner.java as JUnit, everything passes, but I get the following in the console:
0 Scenarios
0 Steps
0m0.000s
WHY? In fact, when I remove CucumberJava.java from the project, I get the exact same output. What am I missing?
I also tried setting the glue option in TestRunner.java code too; still the same result.
Your help is highly appreciated.
The feature file words like Given etc are in uppercase in your feature file. They need to be like Given ie sentence case.
Feature: Simple Test Feature
Scenario: Run Scenario ONE
Given step one
When step two
Then step three
Also you might need to append a 'src' to the feature path in the runner. Like this features = "src/test/resources/features", if you are using Maven. Also no need to have a #Test annotation and method inside the runner.
I am trying to generate the step definitions from my feature file and as well as I have also designed test runner class but upon execution both give output on console as :-
0 scenarios
0 steps
0m0s.000s
Even though my feature file contains scenarios and steps.
Remove the colon (:) after the keywords (Given, When, etc) in your feature file.
Since you haven't shared any code or much details as to what you've done the only assumption that I can make is you have done something wrong in your testrunner class.
#RunWith(Cucumber.class)
#CucumberOptions(
features = "Feature"
,glue={"stepDefinition"}
)
public class TestRunner {
}
in the features make sure the path to your feature files is correct. i.e. if they are stored at some other directory, provide the path for the same
Ex: features = {"src/test/java/features"}
Also, please share your project structure, your feature file and your testrunner class code if possible in case this doesn't work for you.
Actually my runner class file looks like this:-
package runner;
import org.testng.annotations.Test;
import cucumber.api.CucumberOptions;
import cucumber.api.testng.AbstractTestNGCucumberTests;
#CucumberOptions(features={"src//test//resources//featurefiles"},glue= {"im801clsteps"},plugin={"html:target/cucumber-html-report",
"json:target/cucumber.json", "pretty:target/cucumber-pretty.txt"})
#Test
public class MainRunner extends AbstractTestNGCucumberTests {
}
And I am using testng not junit to run my tests,please let me know why I am wrong?
I am new to cucumber and wanted to understand if there is any plugin to generate java test class code from a cucumber feature file.
Example : I have the below scenario -
Scenario: Determine past date
Given today is 2011-01-20
When I ask if Jan 19, 2011 is in the past
Then the result should be yes
Is there a way to generate test class with the methods for each?
I am just looking to generate the skeleton of the class so that it speeds up the development process.
You can run the feature with a runner class like:
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
#RunWith(Cucumber.class)
#CucumberOptions(
dryRun = false,
strict = true,
plugin = {"pretty"},
features = {"path/to/features"},
glue = {"package.of.steps"},
tags = {"#TagsToRun"})
public class MyCucumberTestRunnner {
public MyCucumberTestRunnner() {
}
}
This can be executed as JUnit Test and Cucumber will tell you, that there are missing steps and will provide you the Step Skeletons.
if the glue code is in the same package you dont need to provide the information
Is it possible to run JUnit tests for multiple packages at the same time without manually creating test suites.
For example if I have the hierarchy:
code.branchone
code.branchone.aaa
code.branchone.bbb
code.branchtwo
code.branchtwo.aaa
code.branchtwo.bbb
Is it possible to:
Run all tests in code.branchone and in descendent packages
Run all tests in say code.branchone.aaa and code.branchtwo.bbb
The problem I see with manually creating test suites is that when new tests come along you may forget to add them.
Yes, it is possible. The easiest way for me at least is to add a test suite class. It can look like this:
package tests;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import tests.message.ATest;
import tests.validator.BTest;
import tests.validator.CTest;
import tests.validator.DTest;
#RunWith(Suite.class)
#SuiteClasses({ ATest.class,
BTest.class,
CTest.class,
DTest.class })
public class AllTests {
}
This will allow you to test any class that you import no matter what package it is in. To run this in eclipse you just right click the AllTests class and run it as JUnit test. It will then run all the tests you define in #SuiteClasses.
This will work with linked sources as well, I use it all the time.
An other way:
Click on the black triangle denoted by red rectangle in the picture below (in your Eclipse, not here :).)
Then open run configurations, create a new configuration and then set "Run all tests..." as exemplified in the image below.
Maybe not exactly what the original question was, but you can easily run all tests of a whole Project, by simply right-clicking the project -> Run As JUnitTest. Don't worry where the annotated classes reside, this will be scanned.
This does not work if applied to the test-src-folder or a package with subpackes. Quite a shame actually -.-
I'm sure u can tweak this a bit. Make a Collection of the CLASSES_DIR property and loop over it in the findClasses method. (junit4)
http://burtbeckwith.com/blog/?p=52
I beleieve that you can add all your test packages to a single directory. If you right click on this directory, then you should find the "run as -> JUnit test" option available. This will run all tests contained in the directory and will catch anything you've added. Any new tests get put in there with the rest of them and whatever package name you have it doesn't matter. Hope that helps
Sure, right-click on the packages you want, and select Run As... JUnit Test
In Eclipse, on your debug/run configurations you have the following options:
Run a single test
Run all tests in the selected project, package or source folder
I think the second option is your friend in this case.
If you are using JUnit 5 you can cherry pick which tests you want to run:
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;
import tests.Test1;
import tests.Test2;
import tests.Test3;
#Suite
#SelectClasses({
Test1.class,
Test2.class,
Test3.class
})
public class AllMyTests {
}
If you want to select which packages to run you can:
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;
#Suite
#SelectPackages({
"com.package1",
"com.package2",
"com.package3"
})
public class AllMyTests {
}
If you need to be able to exclude certain sub-packages you can do:
import org.junit.platform.suite.api.ExcludePackages;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;
#Suite
#SelectPackages({
"com.package1",
"com.package2",
"com.package3"
})
#ExcludePackages({
"com.package1.subpackage",
"com.package2.othersubpackage"
})
public class AllMyTests {
}
Other useful annotations:
To match a particular pattern:
#IncludeClassNamePatterns({"^.*ATests?$"})
To exclude a particular pattern:
#ExcludeClassNamePatterns({"^.*ATests?$"})
Examples were based on: https://howtodoinjava.com/junit5/junit5-test-suites-examples/