What Is Behavior Driven Development?
Advantages Of Using BDD For Automation Testing With Selenium & Cucumber
How Cucumber Leverages BDD For Selenium Automation Testing?
- GIVEN: Define pre-requisites of the application.
- WHEN: Trigger point for a scenario execution can be related more towards steps to be executed.
- THEN: Defined an outcome more like the expected result.
- AND: Acts as a logical bridge AND in between two statements.
Feature: Place order on the Amazon website.
@SmokeTest
Scenario: Validate if the guest user is able to add a product to cart.
GIVEN user is logged onto the Amazon website as a guest user.
WHEN user searches a product on the homepage.
THEN user should be able to view product information related to product searched.
AND user click on add to cart button
THEN user verifies if the product is added to cart
Scenario Outline: Validate if a registered user is able to place an order.
GIVEN user is logged onto the Amazon website as a registered user.
WHEN user logs in with <username> and <password>
THEN user should be able to view homepage.
WHEN user searches for <productID>
THEN user should be on the product information page.
AND user tried to add the product to cart
THEN product should be added to cart.
WHEN user navigates to order confirmation page via express checkout option.
THEN order should be placed successfully along with order confirmation id being generated.
@Given("^user is logged onto Amazon website as a guest user $")
public void user_is_on_Home_Page() throws Throwable {
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.get("http://www.amazon.in");
}
@When("^user searches a product on homepage $")
public void user_searches_a_product() throws Throwable {
driver.findElement(By.xpath(".//*[@id='account']/a")).click();
}
package amazonTest;
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/test/Feature"
,glue={"src/main/stepDefinition"}
)
public class TestRunner {
}
Creating Your First Project Using Cucumber For Selenium Automation Testing
“cucumber-archetype Artifact Id
Group Id as io.cucumber”
GroupId: “io.cucumber”
ArtifactId: “cucumber-archetype”
Version: “2.3.1.2”
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Google_Search</groupId>
<artifactId>Google_Search</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Google_Search</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.14.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>4.2.2</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>27.0.1-jre</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>4.2.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Step 1: Create a folder for organizing all your feature files as shown in the image below.
Step 2: Select File from the navigation menu. File → New → File.
Step 3: Name the file using “Login.feature”.
Step 4: As there is no plugin which supports “.feature” extension file created would look as in the image below.
Click on install. Accept the terms of the license agreement. Click on Finish. You would be prompted with a security alert, click on Install Anyway option, once installation is finished click on Restart Now to view the changes made.
Running First Script Of Automated Testing With Selenium & Cucumber Framework
Feature: Searching Google should return the name of query
Scenario: Google search with scenario
Given user launches Google webapp
When user searches for a "LambdaTest"
And click on search button
Then results retrieved should contain the "LambdaTest" used
Scenario Outline: Searching google using scenario outline and examples
Given user launches Google webapp
When user searches for a "<query>"
And click on search button
Then results retrieved should contain the "<query>" used
In order to resolve the errors, lets navigate to the step definition file to complete coding the gist which defines our steps.
Below code can be replaced in step definition file which is Stepdefs.
TIP:
package com.googlesearch.testing.steps;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import cucumber.api.java.en.And;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class stepDefinitions {
public static WebDriver driver;
String baseURL = "https://www.google.com";
@Given("^user launches Google webapp$")
public void user_launches_Google_webapp() throws Throwable {
// Write code here that turns the phrase above into concrete actions
System.setProperty("webdriver.chrome.driver", "C:\\Cucumber_Workspace\\GoogleSearch\\Libs\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get(baseURL);
}
@When("^user searches for a \"([^\"]*)\"$")
public void user_searches_for_a(String arg1) throws Throwable {
WebElement searchBox = driver.findElement(By.name("q"));
searchBox.sendKeys(arg1);
}
@And("^click on search button$")
public void click_on_search_button() throws Throwable {
WebElement searchBox = driver.findElement(By.name("q"));
searchBox.submit();
}
@Then("^results retreived should contain the \"([^\"]*)\" used$")
public void results_retreived_should_contain_the_used(String resultString) throws Throwable {
WebElement result = driver.findElement(By.className("LC20lb"));
if (resultString.equalsIgnoreCase(result.getText())) {
System.out.println("Text is matching");
} else {
System.out.println("Text is not matching");
}
driver.quit();
}
}
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
@RunWith(Cucumber.class)
@CucumberOptions(features = { "classpath:features" }, plugin = { "pretty", "json:target/cucumber/cucumber.json" })
public class RunCucumberTest {
}
Using LamdaTest For Automation Testing With Selenium & Cucumber
Configuring Your Test Suite With LambdaTest For Parallel Test Execution Of Selenium With Cucumber & TestNG
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="GoogleSearch" parallel="tests" thread-count="3">
<test name="WIN10TEST_FF">
<parameter name="browser" value="Firefox" />
<parameter name="version" value="64.0" />
<classes>
<class name="com.cucumber.tests.TestNGRunCucumberTest" />
</classes>
</test>
<test name="WIN10TEST_CHROME">
<parameter name="browser" value="Chrome" />
<parameter name="version" value="71.0" />
<classes>
<class name="com.cucumber.tests.TestNGRunCucumberTest" />
</classes>
</test>
</suite>
package com.cucumber.stepdefs;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import com.cucumber.tests.TestNGRunCucumberTest;
import cucumber.api.java.en.And;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class stepDefinitions extends TestNGRunCucumberTest {
@Given("^user launches Google webapp$")
public void user_launches_Google_webapp() throws Throwable {
// Write code here that turns the phrase above into concrete actions
driver.get(baseURL);
}
@When("^user searches for a \"([^\"]*)\"$")
public void user_searches_for_a(String arg1) throws Throwable {
WebElement searchBox = driver.findElement(By.name("q"));
searchBox.sendKeys(arg1);
}
@And("^click on search button$")
public void click_on_search_button() throws Throwable {
WebElement searchBox = driver.findElement(By.name("q"));
searchBox.submit();
}
@Then("^results retreived should contain the \"([^\"]*)\" used$")
public void results_retreived_should_contain_the_used(String resultString) throws Throwable {
WebElement result = driver.findElement(By.xpath("//*[@id='rhscol'][1]"));
if (result.isDisplayed()) {
System.out.println("Resutls are retreived");
} else {
System.out.println("Resutls are not retreived");
}
}
}
package com.cucumber.stepdefs;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import com.cucumber.tests.TestNGRunCucumberTest;
import cucumber.api.java.en.And;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class stepDefinitions extends TestNGRunCucumberTest {
@Given("^user launches Google webapp$")
public void user_launches_Google_webapp() throws Throwable {
// Write code here that turns the phrase above into concrete actions
driver.get(baseURL);
}
@When("^user searches for a \"([^\"]*)\"$")
public void user_searches_for_a(String arg1) throws Throwable {
WebElement searchBox = driver.findElement(By.name("q"));
searchBox.sendKeys(arg1);
}
@And("^click on search button$")
public void click_on_search_button() throws Throwable {
WebElement searchBox = driver.findElement(By.name("q"));
searchBox.submit();
}
@Then("^results retreived should contain the \"([^\"]*)\" used$")
public void results_retreived_should_contain_the_used(String resultString) throws Throwable {
WebElement result = driver.findElement(By.xpath("//*[@id='rhscol'][1]"));
if (result.isDisplayed()) {
System.out.println("Resutls are retreived");
} else {
System.out.println("Resutls are not retreived");
}
}
}
As we have trigger the tests from xml file of TestNG we can replace the TestRunner file with below code, as our entry point would be TestNGRunner xml.
package com.cucumber.tests;
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
import cucumber.api.CucumberOptions;
import cucumber.api.testng.CucumberFeatureWrapper;
import cucumber.api.testng.PickleEventWrapper;
import cucumber.api.testng.TestNGCucumberRunner;
@CucumberOptions(features = { "src/test/java/features" }, glue = { "com.cucumber.stepdefs" }, plugin = { "pretty",
"json:target/cucumber/cucumber.json" })
public class TestNGRunCucumberTest {
DesiredCapabilities capabilities = new DesiredCapabilities();
String username = " bharadwajpendyala";
String accesskey = " qYlLn1IzVrC2U41zM4kyjv35EvpHxR2tyMB4aEBlkNMmvpnQ5A";
protected static RemoteWebDriver driver = null;
String gridURL = "@hub.lambdatest.com/wd/hub";
boolean status = false;
protected String baseURL = "https://www.google.com";
private TestNGCucumberRunner testNGCucumberRunner;
@BeforeClass
@Parameters(value = { "browser", "version" })
public void beforeClass(String browser, float version) {
capabilities.setCapability("build", "Cucumber_Project");
capabilities.setCapability("name", "Querying in google engine");
capabilities.setCapability("platform", "Windows 10");
capabilities.setCapability("browserName", browser);
capabilities.setCapability("version", version);
try {
driver = new RemoteWebDriver(new URL("https://" + username + ":" + accesskey + gridURL), capabilities);
} catch (MalformedURLException e) {
System.out.println("Invalid grid URL");
} catch (Exception e) {
System.out.println(e.getMessage());
}
testNGCucumberRunner = new TestNGCucumberRunner(this.getClass());
}
@Test(groups = "cucumber scenarios", description = "Runs Cucumber Scenarios", dataProvider = "scenarios")
public void scenario(PickleEventWrapper pickleEvent, CucumberFeatureWrapper cucumberFeature) throws Throwable {
testNGCucumberRunner.runScenario(pickleEvent.getPickleEvent());
}
/**
* @return returns two dimensional array of {@link CucumberFeatureWrapper}
* objects.
*/
@DataProvider
public Object[][] scenarios() {
return testNGCucumberRunner.provideScenarios();
}
@AfterClass
public void tearDown() {
driver.quit();
testNGCucumberRunner.finish();
}
}