How to run multiple feature files using the cucumber runner class? - selenium

Using the below line of code, all scenarios mentioned in login.feature can be executed.
#CucumberOptions(features= "src/main/resources/publish/login.feature", format = {"pretty"} )
If I have to execute multiple feature files, how do I define? Assuming if I define as below, features mentioned in publish folder would be executed.
#CucumberOptions(features= "src/main/resources/publish", format = {"pretty"} )
If I have to run multiple features and scenarios inside it, how do I define? Do i have to create multile cucumberRunner classes or i can define in one class file.

You can do it by defining tags value in cucumber option(considering that you have already grouped those scenarios in feature files)
Eg:
features="src/test/resources/FeatureFiles",tags="#feature1scenariogroup1,#feature2cenariogroup2"
Defining Tags Inside Feature File:
Feature: My Feature File
#smoke
Scenario: Login
Given I open "FireFox" browser
When I navigate to Sectionone "Home" page
And i do something
Then I Validate Something
#regression
Scenario: Compose Email
Given I open "FireFox" browser
When I Do An Action
#OnlyOneTime
Scenario:Send Email
....

Try this, the below code works for multiple feature files (tags attribute only works when you want to run particular scenario), I tried the below for multiple feature files, it worked:
#CucumberOptions(features = {"src\\test\\resources\\cucumberfeaturefolder\\cucumber1.feature",
"src\\test\\resources\\cucumberfeaturefolder\\cucumber2.feature"},
glue= "StepDef")

You can either use selective feature file or selective scenarios in the feature using tags. Please try with this solution.
Lets consider the you have n number of feature files and you need to run only selective feature from that. Then name each feature file with #tag name.
eg.: Under this folder, if you are having n number of features - "src/main/resources/publish"
1st Feature file name:
Login.feature
//Inside the file start with feature tag name
#Login
Feature: To Login to Email
//Then feature name followed with scenario tag name
#User
//Scenario1:
Scenario Outline: Navigate and logon to gmail application
Given User launches gmail application
When User updates emailID <emailID>
And User updates pwd <pwd>
Then User clicks on Login Button
Examples:
| emailID | pwd |
| a#gmail.com| 123 |
2nd Feature File name:
CreateEmail.feature
#Createmail
Feature: Create email
Scenario: Blah blah blah...
//Write all Given when And Then
3rd Feature File name:
SendEmail.feature
#Sendemail
Feature: Send email
Scenario: Blah blah blah...
//Write all Given when And Then
So From the above Test files. Lets consider you want to test 1st and 3rd feature alone, Then you can use code as below:
eg.: # This is to run specific feature files, which is 1 and 3. Likewise you can use the tags for scenario as well if you have n number scenario in same feature file.
#CucumberOptions(features= "src/main/resources/publish", tags="#Login, #Sendemail", format = {"pretty"} )

Modified my code like to run all enabled features, scenarios. features is the point to note here for the runner class to consider the features
#RunWith(Cucumber.class)
#CucumberOptions(
features = {"classpath:features"},
plugin = {"html:target/site/cucumber-pretty","json:target/cucumber.json"},
tags = {"#currentTest"},
glue={"helpers","stepDefinitions"},
// dryRun = true,
monochrome = true
)
public class RunCukesTest{
}

You can simply write tags = {"#fileName1, #fileName2"}
We can add multiple files using #File1, #File2,..

#RunWith(Cucumber.class)
#CucumberOptions(
features = {"src/test/java/Features"},
tags= {"#FirstTimeLaunch, #SignUpPage"},
glue= {"testCode"},
plugin = { "pretty", "html:target/htmlreports" }
)
Here all *.feature files inside your Features folder (Package) will be executed in the Alphabetic order of the file name, when you execute as a Junit test ( runner class )

Following code working for me:
(1) BeerCans.feature
Feature: Beer Cans
Scenario: Counting Beer Cans
Given I have <opening balance> beer cans
And I have drunk processed beer cans
When I go to my fridge
Then I should have <in stock> beer cans
(2) multiplication.feature
Feature: Multiplication
I multiply two numbers
Scenario: multiple a and b
Given I have variable a
And I have variable b
When I multiply a and b
Then I display the Result
(3) MyStepdefs class
package org.example.njain51.steps; /**
* #author : Nitin Jain
* #mailto : official.nitinjain#gmail.com
* #created : 5/22/2022, Sunday
**/
import io.cucumber.java.en.And;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
/**
What this program snippet doing?
**/
public class MyStepdefs {
#Given("I have <opening balance> beer cans")
public void iHaveOpeningBalanceBeerCans() {
System.out.println("I have Opening Balance");
}
#And("I have drunk processed beer cans")
public void iHaveDrunkProcessedBeerCans() {
}
#When("I go to my fridge")
public void iGoToMyFridge() {
System.out.println("I go to my Fridge");
}
#Then("I should have <in stock> beer cans")
public void iShouldHaveInStockBeetCans() {
System.out.println("I should have in stock beer cans");
}
}
(4) MultiplicationStepDef class
package org.example.njain51.steps; /**
* #author : Nitin Jain
* #mailto : official.nitinjain#gmail.com
* #created : 5/22/2022, Sunday
**/
import io.cucumber.java.en.And;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
/**
What this program snippet doing?
**/
public class MultiplicationStepDef {
#Given("I have variable a")
public void iHaveVariableA() {
System.out.println("I have variable a");
}
#And("I have variable b")
public void iHaveVariableB() {
System.out.println("I have variable b");
}
#When("I multiply a and b")
public void iMultiplyAAndB() {
System.out.println("I Multiply a and b");
}
#Then("I display the Result")
public void iDispayTheResult() {
System.out.println("I Display the result");
}
}
(5) RunCucumberTest Class for multiple feature implementation
package org.example.njain51;/**
* #author : Nitin Jain
* #mailto : official.nitinjain#gmail.com
* #created : 5/22/2022, Sunday
**/
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
#RunWith(Cucumber.class)
#CucumberOptions(
features = {"src/test/resources/features/BeerCans.feature",
"src/test/resources/features/multiplication.feature"},
glue = {"org.example.njain51.steps"})
public class RunCucumberTest {
}
(6) Output when I run RunCucumberTest
C:\Users\offic\.jdks\corretto-1.8.0_292\bin\java.exe -ea -DnodeNamesHandler=org.jetbrains.plugins.cucumber.java.run.CucumberTestTreeNodeManager -Didea.test.cyclic.buffer.size=1048576 "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.1\lib\idea_rt.jar=49946:C:\Program Files\JetBrains\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\JetBrains\IntelliJ IDEA 2021.1\lib\idea_rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2021.1\plugins\junit\lib\junit5-rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2021.1\plugins\junit\lib\junit-rt.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\charsets.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\access-bridge-64.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\cldrdata.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\dnsns.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\jaccess.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\jfxrt.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\localedata.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\nashorn.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\sunec.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\sunjce_provider.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\sunmscapi.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\sunpkcs11.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\ext\zipfs.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\jce.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\jfr.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\jfxswt.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\jsse.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\management-agent.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\resources.jar;C:\Users\offic\.jdks\corretto-1.8.0_292\jre\lib\rt.jar;D:\mylearning\SAMPLE_PROJECTS\Testing\cucumber-demo\target\test-classes;C:\Users\offic\.m2\repository\io\cucumber\cucumber-java\6.1.1\cucumber-java-6.1.1.jar;C:\Users\offic\.m2\repository\io\cucumber\cucumber-core\6.1.1\cucumber-core-6.1.1.jar;C:\Users\offic\.m2\repository\io\cucumber\cucumber-gherkin\6.1.1\cucumber-gherkin-6.1.1.jar;C:\Users\offic\.m2\repository\io\cucumber\cucumber-gherkin-messages\6.1.1\cucumber-gherkin-messages-6.1.1.jar;C:\Users\offic\.m2\repository\io\cucumber\messages\12.1.1\messages-12.1.1.jar;C:\Users\offic\.m2\repository\io\cucumber\tag-expressions\3.0.0\tag-expressions-3.0.0.jar;C:\Users\offic\.m2\repository\io\cucumber\cucumber-expressions\10.2.0\cucumber-expressions-10.2.0.jar;C:\Users\offic\.m2\repository\io\cucumber\datatable\3.3.1\datatable-3.3.1.jar;C:\Users\offic\.m2\repository\io\cucumber\cucumber-plugin\6.1.1\cucumber-plugin-6.1.1.jar;C:\Users\offic\.m2\repository\io\cucumber\docstring\6.1.1\docstring-6.1.1.jar;C:\Users\offic\.m2\repository\io\cucumber\html-formatter\6.0.3\html-formatter-6.0.3.jar;C:\Users\offic\.m2\repository\org\apiguardian\apiguardian-api\1.1.0\apiguardian-api-1.1.0.jar;C:\Users\offic\.m2\repository\io\cucumber\cucumber-junit\6.1.1\cucumber-junit-6.1.1.jar;C:\Users\offic\.m2\repository\junit\junit\4.13\junit-4.13.jar;C:\Users\offic\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2021.1\plugins\cucumber-java\lib\cucumber-jvmFormatter.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 org.example.njain51.RunCucumberTest
I have Opening Balance
I go to my Fridge
I should have in stock beer cans
I have variable a
I have variable b
I Multiply a and b
I Display the result
Process finished with exit code 0

Related

Is there a way in karate to make use of TestExecutionListener from Junit5? [duplicate]

This question already has an answer here:
Karate summary reports not showing all tested features after upgrade to 1.0.0
(1 answer)
Closed 1 year ago.
I am trying to make use of https://junit.org/junit5/docs/current/user-guide/#launcher-api-listeners-custom, created my own Listener that implements TestExecutionListener:
public class JunitTestListener implements TestExecutionListener {
public static final Logger logger = LoggerFactory.getLogger(JunitTestListener.class);
/**
* Called when the execution of the {#link TestPlan} has finished,
* <em>after</em> all tests have been executed.
*
* #param testPlan describes the tree of tests that have been executed
*/
#Override
public void testPlanExecutionFinished(TestPlan testPlan) {
logger.info("Mutzu was here");
}
#Override
public void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) {
logger.info("Mutzu was here");
}
}
I have create META-INF/services/org.junit.platform.launcher.TestExecutionListener and added there the custom listener class, however it is not called when running with Karate:
import com.intuit.karate.junit5.Karate;
class E2ETest {
// this will run all *.feature files that exist in sub-directories
// see https://github.com/intuit/karate#naming-conventions
#Karate.Test
Karate testAll() {
return Karate.run().relativeTo(getClass());
}
}
Any idea on how to make it work?
Thanks!
It seems that with this ExecutionHook I can have access to after/before step/scenario/feature however I cannot control the result of a scenario made up of other scenarios.
I can't possibly know in ExecutionHook what is a result of a "test", test in my acceptance meaning a scenario defined and composed with other scenarios. For example, if I have:
Background:
* def feature1 = read('classpath:create_schema.feature')
* def feature2 = read('classpath:create_dataset.feature')
* def feature3 = read('classpath:create_mergepolicy.feature')
Scenario: Some test
Given def schema = call feature1
And def schemaId = schema.schemaId
Given def datasetArg = { schemaId: '#(schemaId)' }
And def dataset = call feature2 datasetArg
And def datasetId = dataset.datasetId
Given def mergePolicyArg = { datasetId: '#(datasetId)' }
And def mergePolicy = call feature3 mergePolicyArg
And def mergePolicyId = mergePolicy.mergePolicyId
If there is a failure at some step, let's say call within feature1, then with ExecutionHook I get the failing event 2 times, one for scenario failing within feature1 and then another fail for Scenario: Some test, which is the test I run.
Any idea on how to have a single event triggered if some step fails in Scenario: Some test?
The Karate JUnit5 support is based on DynamicNode and is known to be not bound by the usual life-cycle. It is intended to make the developer experience better in IntelliJ and Eclipse, that's all.
Maybe you should be looking at the Karate ExecutionHook instead.

How we can run more than one feature files and all feature files depending on the requirement using same runner class?

I have 5 feature files I want to run some feature files depends on the requirement using one runner class only is it possible and if then how?
1) You can run required feature adding path to the feature in Karate Options:
#RunWith(Karate.class)
#KarateOptions(features = "classpath:animals/cats/required.feature")
public class CatsPostRunner {
}
2) You can run required feature or scenario adding a tag to the feature or scenario and in Karate Options:
#RunWith(Karate.class)
#KarateOptions(tags = "#someTag")
public class CatsPostRunner {
}
3) Also you can combine approach 1 and 2 :
#RunWith(Karate.class)
#KarateOptions(features = "classpath:animals/cats/required.feature", tags = "#someTag")
public class CatsPostRunner {
}
More info you find in Karate Options.

Cucumber- // Write code here that turns the phrase above into concrete actions

I Tried to execute the same test with different data but I am getting the following error when I tried to run the test
You can implement missing steps with the snippets below:
#When("^Enter the ADMIN and password(\\d+)$")
public void enter_the_ADMIN_and_password(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
Below is my Feature file
Scenario Outline: Login
Given Open chrome and login
When Enter the <Username> and <Password>
Then Click on Login
Examples:
|Username |Password |
|ADMIN |password123|
Below is the #when annotation part in Steps file
#When("^Enter the \"(.*)\" and \"(.*)\"$")
public void enter_the_Username_and_Password(String username,String Password) throws Throwable
{
System.out.println("This step enter the Username and Password on the login page."+username +Password);
loginObj.Login(driver);
}
It may be occurring due to cucumbers packages is misconfigured. Check the GLUE options
#RunWith(Cucumber.class)
#CucumberOptions(
features = { "src/test/resources/features/CucumberTests.feature" },
tags = { "#integration_test"},
glue = { "br.com.cucumber.integration.stepDefinition" },
format = { "pretty", "html:target/reports/cucumber/html", "json:target/cucumber.json", "usage:target/usage.jsonx", "junit:target/junit.xml" })
#ContextConfiguration(classes= AppConfiguration.class)
public class CumcumberTest extends BaseTestCase {
}
I think what you are describing as an "error" is in fact cucumber telling you that is not able to find the matching definition for the step "When Enter the Username and Password" and has auto-generated the example definition below based on the scenario outline data:
#When("^Enter the ADMIN and password(\\d+)$")
public void enter_the_ADMIN_and_password(int arg1) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
The problem is that your step definition is using quotes on the parameters but your actual step has no quotes, hence cucumber is not able to match them. You either need to change your step in the feature file to include quotes:
When Enter the "<Username>" and "<Password>"
Or you need to change the step definition to not include quotes:
#When("^Enter the (.*) and (.*)$")
public void enter_the_Username_and_Password(String username,String Password) throws Throwable
{
System.out.println("This step enter the Username and Password on the login page."+username +Password);
loginObj.Login(driver);
}
I got the same error. For me the problem was that I created step definition in the package for back end tests instead of front end ones. If the step definition classes have same or similar names, it is possible to make a mistake. This would happen during chosing the wrong package while creating step definition from the feature file in Intellij.
I was getting this issue and discovered the reason was I accidentally gave the name of the class and not the package for the glue code:
The wrong argument value for my gluecode was my class as: gluecode="StepDefinition", when it should have been my package: gluecode="stepDefs"
My TestRunner.java looks as follows:
package testRunner;
import org.junit.runner.RunWith;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
#RunWith(Cucumber.class)
#CucumberOptions(
features = "src/test/java/features",
glue = "stepDefs")
public class TestRunner {
}
I got the same error. In my case I was forgetting the .step. part in my file name.
So I've solved by modifying my file name from:
mystepfile.ts
to:
mystepfile.step.ts

Selenium framework and test data in json

I am just completed a test automation using with selenium. And I want to know about how to keep the test data separately in json format.
Can you please tell me how to write test data in the page object pattern.
Here I am using multiple packages. One is for locators identification, another is for page factory for initializing elements, and the other is package utilities for common values like get URL. I also have a test package for testing a login module.
What I don't know is where should I put the test data class ?
I want to keep the test data separately. Not scattering all over the script. Keep the test data in Json. And read it from there where ever it is necessary.
Still I'm getting confusing about where Should I put the json format
And also I am selenium code doesn't follow a framework. I did n't follow any frameworks. Anybody please tell me about frameworks ?
Frameworks are : Data driven, keyword driven, hybrid and modular. which framework is most people using , because and why ?
As a tester should have knowledge about all frameworks ?
I am following page object design pattern:
Page object :
package pageobjects;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
public class HomePage
{
#FindBy(how= How.NAME, using = "username")
WebElement username;
#FindBy(how=How.NAME, using = "password")
WebElement password;
#FindBy(how=How.XPATH, using="//*[#id=\'login-container\']/form/div[3]/div/p/input[1]" )
WebElement button;
//enter username
public void userLogin(String user, String pass)
{
username.sendKeys(user);
password.sendKeys(pass);
button.click();
}
}
Steps:
package steps;
import org.openqa.selenium.support.PageFactory;
import pageobjects.ClientPage;
import pageobjects.HomePage;
import util.DriverManager;
public class LoginSteps
{
public HomePage Login(String nam, String pas) {
HomePage homePageObj = PageFactory.initElements(DriverManager.driver, HomePage.class);
homePageObj.userLogin(nam,pas);
return homePageObj;
}
}
Util:
package util;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class DriverManager
{
public static WebDriver driver;
String baseUrl="//http:qms";
public DriverManager()
{
System.setProperty("webdriver.chrome.driver","/home/naveen/chromedriver");
driver=new ChromeDriver();
driver.get(baseUrl);
driver.manage().window().maximize();
}
}
Login Test :
package login;
import org.testng.Assert;
import org.testng.annotations.*;
import pageobjects.HomePage;
import steps.LoginSteps;
import util.DriverManager;
import static util.DriverManager.driver;
public class loginTest
{
#BeforeSuite(groups = {"regression"})
public void initDriver(){
DriverManager manager = new DriverManager();
}
#DataProvider(name= "login")
public static java.lang.Object[][] loginData(){
return new Object[][]{{"geoso","1"},{"ges","2"},{"geo","1"}};
}
#Test(dataProvider = "login")
public void verifyValidLoginWithDataProvider(String userName,String password)
{
LoginSteps loginSteps= new LoginSteps();
HomePage ex=loginSteps.Login(userName,password);
Assert.assertTrue(driver.getPageSource().contains("Hello Naveen"));
}
}
Here is the scenario of json format Please tell me how to write the code?
first open URL and go to login page then .
login
{
"username" :"ertte"
password: "34"
}
"Admin"
"users"
"add users"
"username" :"tsrt"
"password":"sdfgsdrfg"
name:"gfgf"
nickname:"fgsdgf"
role:"client"
email:"sdfsd#gmail.com"
submit
}}
There are so many different frameworks you can use now in combination with selenium.
I use Cucumber [BDD].
You can write your scenarios as regular sentences and Gherkin will transfer them in a methods. Sentences can have parameters or list of a parameters.
You have execution control for your test at two, let call it top levels. You can choose which feature file you want to ran.
Second execution filter can be build by using tags. For e.g. #smoketest #regression and so on.
You can use also TestNG. You have .xml file where you can make your setup. Execute particular clases, methods, prioretize test, make test dependencies, skip tests, and have full control over execution.
There are lot more I assume but these two are the most popular.

behat 3 - Using constructor breaks output

I followed the tutorial on http://docs.behat.org/en/latest/quick_intro_pt1.html.
But when I have implemented the feature and running behat it is said in the tutorial that I should get an error: "Fatal error: Class 'Shelf' not found."
I did not get that error. Only the output of the user story:
$ vendor/bin/behat
Feature: Product basket
In order to buy products
As a customer
I need to be able to put interesting products into a basket
Rules:
- VAT is 20%
- Delivery for basket under £10 is £3
- Delivery for basket over £10 is £2
class FeatureContext implements SnippetAcceptingContext
{
private $shelf;
private $basket;
public function __construct()
{
$this->shelf = new Shelf();
$this->basket = new Basket($this->shelf);
}
/**
* #Given there is a :product, which costs £:price
*/
public function thereIsAWhichCostsPs($product, $price)
{
$this->shelf->setProductPrice($product, floatval($price));
}
It looks like, when I am using a constructor this happening and the output of behat is just the user story but not the tests.
Even if I put an exit() in the function the exit() is not happening.
I have tried this with different projects in PHPStorm. It is always the same.
I am wondering how I could get the expectedt error: "Fatal error: Class 'Shelf' not found."
I am using behat 3.0.14: I have used composer to install it.