Cucumber - BDD Framework

Agenda

To understand Cucumber BDD framework and its features.

Prerequisite

  1. install JDK on your machine >1.7
  2. IntelliJ IDE with plugins - "Cucumber for Java, Gherkin"

What is BDD?

  1. It's a development approach that can be understood by tech and non tech folks.
  2. Usually this is expressed in Given, when, then statements.
  3. Gherkin is the language used to achieve this, which let's you describe business scenario.

Keywords

  1. Test cases are represented as scenario.
  2. Preconditions are generally defined in Given.
  3. To describe user action we use When
  4. To validate output we use Then
  5. To validate negative scenarios use But

Lets take a look at an example

Scenario: Checkout cart items
Given user is on product page
When user adds products to cart
And click on checkout button
Then product items should be displayed in billing page

  1. High level business requirement is defined under Feature Ex: Feature: Checkout
  2. Feature file is a test suite that contains all scenarios.
  3. Step definitions will have the code that need to be executed for Given, when, then etc.
  4. Junit Test Runner used to run the feature files

Create simple maven project

  1. while creating maven project - use maven-archetype-quickstart archetype, so that maven builds the skeleton for you.
  2. app dependencies to pom.xml for cucumber-java, cucumber-junit
<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-java -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>7.2.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-junit -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>7.2.3</version>
<scope>test</scope>
</dependency>

Getting Started

Create a feature file

Login.feature
Feature: Portal Login
Scenario: Test for Home page
Given User is on landing page
When User logins with username and password
Then Use should land on Home page
Mapping Step Definitions
public class StepDefinition {
@Given("^User is on landing page$")
public void user_is_on_landing_page(){
System.out.println("User is on landing page");
}

@When("^User logins with username and password$")
public void user_logins_with_username_and_password(){
System.out.println("User logins with username and password");
}

@Then("^User should land on Home page$")
public void user_should_land_on_Home_page(){
System.out.println("User should land on Home page");
}
}

you can also generate steps definitions using chrome plugin - Tidy Gherkin
Runner file through which you run your feature file
mport io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;

@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/test/java/features",
glue = "stepDefinitions", stepNotifications = true
)
public class TestRunner {
}
Note: Make sure to have your features, step definitions and runner files under src/test/java folder.

You can even create Runner file with TestNG with maven dependency - cucumber-testng
package runners;

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;

@CucumberOptions(
features = "src/test/java/features",
glue = "stepDefinitions"
)
public class TestNGRunner extends AbstractTestNGCucumberTests {
}
Note: Use either Junit or TestNG, don't use both of them.

Parameterizing your tests

data drive using arguments

in feature file we have like this, where username and password fields are parameterized.
When User logins with "username" and "password"
in step definition we need to have regex like below
@When("^User logins with \"([^\"]*)\" and \"([^\"]*)\"$")
public void user_logins_with_something_and_something(String userName, String password){
System.out.println("user logins with username: "+userName+" and password: "+password);
}

data drive  using multiple arguments (datatable)

feature file
Scenario: Test for sign up
Given User is on landing page
When User sign up with following details
|john|walker|john.walker@gmail.com|India|Bangalore|
Then User should land on Home page
step definition
@When("^User sign up with following details$")
public void user_sign_up_with_following_details(DataTable dataTable){
List<List<String>> signUpData = dataTable.asLists();
String firstName = signUpData.get(0).get(0);
String lastName = signUpData.get(0).get(1);
String email = signUpData.get(0).get(2);
String country = signUpData.get(0).get(3);
String city = signUpData.get(0).get(4);

System.out.println("Printing "+firstName+"--"+lastName+"--"+email+"--"+country+"--"+city);
}

parameterization

feature file
Scenario Outline: Test for multiple user logins
Given User is on landing page
When User logins with <username> and <password>
Then User should land on Home page
And User account should be <status>
Examples:
|username|password|status|
|john |wick |active|
|james |bond |inactive|
step definition
@When("^User logins with (.+) and (.+)$")
public void user_logins_with_and(String username, String password){
System.out.println("username : "+username+"--- password : "+password);
}

Tagging test cases

you can tag your tests and specify those tags in runner file
feature file
@SmokeTest
Scenario: Test for Inactive Users Home page
Given User is on landing page
When User logins with "username2" and "password2"
Then User should land on Home page
And User account should be "inactive"
Runner file
@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/test/java/features",
glue = "stepDefinitions", stepNotifications = true,
tags = "@SmokeTest"
)
public class JunitTestRunner {
}
tags can be represented like
"@SmokeTest or @SanityTest" - which runs both smoke and sanity tests
"not @SmokeTest" - run all cases except smoke.
"@SmokeTest and @Regression" - which runs tests which are marked for smoke and regression.

Background

It's more of like a prerequisite, which will execute before running a feature file
feature file
Background:
Given Browser should be invoked
When User navigates to portal
define step definitions accordingly.

Hooks

  1. which runs before every scenario and its defined in step definitions.
  2. you can define to run it for specific scenarios as well
Note: Don't use Hooks and Background together

public class Hooks {
@Before("@Mobile")
public void beforeMobile(){
System.out.println("Before Running Mobile Hook");
}

@After("@Mobile")
public void afterMobile(){
System.out.println("After running Mobile hook");
}
}

if you don't use tags, it will run before/after every scenario in feature file.

Reports

pass this attribute in cucumber options
plugin = {"pretty", "html:target/cucumber.html", "json:target/cucumber.json", "junit:target/cukes.xml"},

Cucumber Options - Attributes

Dry run

won't be running test cases, but just a check for step definitions, so that we can implement if any step definitions are missing
dryRun = true

monochrome

improved output and detailed when it is set to true
monochrome = true

Resources

Comments

Popular posts from this blog

TestNg - Test Automation Framework

React Js and Redux

Appium 7 - Android Test Automation