How to start with Cucumber Automation ?

This blog will help you understand, how we can introduce automation to our daily QA processes for executing repeating test cases with an example.

A little insight into Automation with Cucumber :

Automation is a widely used term. But knowing its application at the right place for the right purpose, makes it effective and saves lot of efforts.

Cucumber is an automation framework, which allows conversion of test cases written in simple English to actions using coding. The automation framework mainly follows an approach known as Behaviour Driven Development (BDD) which provides software engineers an opportunity to create test cases from the end user’s perspective. This in turn helps developers, project managers and product owners (stakeholders), QA’s, among others to get together and provide their views about which test scenarios should be executed to make this software/application successful.

A person from non-technical background, who understands the domain and business implementation built into the application, can provide test scenarios that need to be verified. In this manner, a business flow of the application can be automated for testing. This also enables testing of various test data for positive and negative scenarios.

Tools you need to get started :

  1. Java setup
  2. Eclipse setup
  3. PhantomJS setup
  4. Cucumber libraries for Eclipse
  5. Selenium libraries for Eclipse

Advantages of Cucumber over other tools :

  1. Cucumber supports different languages like Java, .net, and Ruby.
  2. It acts as a bridge between the business and technical language.
  3. We can accomplish this by creating a feature file in plain English text, covering the areas that need to be tested.
  4. It allows the test script to be written without knowledge of any code, it allows the involvement of non-programmers as well.
  5. Due to simple test script architecture, Cucumber provides code re-usability.

A prerequisite to writing automated test cases (step_definition) is a basic knowledge of a programming language like Java, Ruby etc.

Following is an example of the same :

1. Create a Cucumber Project using Java in Eclipse

Click on “File” and click on the “New” button and then select “Java Project” from the list.
Enter the name of the Project accordingly and click on finish button.
Project created with name “ADemoApp”.

2. Configuring external jars in the Cucumber Project

Properties specific to the project can be set by right clicking on the project name.
Click on the “Build Path” option and then on the “Configure Build Path” option.
Add external jars related to selenium webdriver, cucumber and gherkin in the Build Path.
Select the latest jar versions that need to be applied to the project and select the ok button to save the jars.

3. Folders required in Cucumber Project

Create folders – Feature, src>>StepDefinitions, src>>PageObjects.
The feature folder contains all the feature related files.
The src folder structure contains the packages – cucumberTest, pageObjects & step_definitions (mandatory).
The pageObjects package contains the java classes related to the pageObjects of a page.
The step_definitions package contains the java classes related to the step_definitions related to the feature file.

4. Writing a Feature File, step_definitions class and TestRunner.java class

@smoke
Feature: Login to Dummy App
I want to test the login to Dummy App

Scenario: Dummy App’s Login
Given I have the permission to Dummy App as an Agent
When I navigate to app’s login url
Then I should be able to view app’s Home Page

The above has been divided into 3 parts :

  1. Tagging : This tags the test case type, if it is a @Smoke, @Regression, @Functional and so on.
  2. Feature : This is a description of the feature that is to be tested
  3. Scenario : This is a description of the scenario that is to be tested. In the above example a positive scenario like valid login flow is tested. It can also include a negative scenario like an invalid login flow. This scenario is divided in three parts :
    1. Given : Is the prerequisite, we have
    2. When : Is the condition that needs to be checked
    3. Then : Is the expected result, portraying that the test was successful.
  4. Feature files are written using Gherkin language
    package step_definition;

import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import driverInitialize.driverInitialize;
import Utilities.*;

public class loginTest {
static driverInitialize d = new driverInitialize();
static WebDriver driver = d.driverInit();
@Given("^I have the permission to Dummy App as an Agent$")
public void valid_agent_id() throws Exception
{
try
{
String url = settings.dummy_app_url();
driver.get(url);
}
catch (Exception e)
{
throw e;
}
}

@When("^I navigate to app’s login url$")
public void login_url() throws Exception
{
try
{
if(pageObjects.callDisposition.fcd_text(driver).isDisplayed())
{
pageObjects.callDisposition.call_dispose_slider(driver).click();
pageObjects.callDisposition.call_dispose_option(driver).click();
pageObjects.callDisposition.apply_button(driver).click();
System.out.println("Forced Call Disposition value set");
}
else
{
System.out.println("Forced Call Disposition page not found");
}
}
catch (Exception e)
{
throw e;
}
}

@Then("^I should be able to view app’s Home Page$")
public void dummy_app_home() throws Exception
{
WebDriverWait wait = new WebDriverWait(driver, 60);
try
{
wait.until(ExpectedConditions.titleContains("Home"));
if(pageObjects.homePage.txt_breadcrumb(driver).getText().contains("Home"))
{
System.out.println("Test Case has passed");
}
else
{
System.out.println("Test Case has failed");
}
driver.quit();
}
catch (Exception e)
{
throw e;
}
}
}
  1. As seen in the above code snippet, the sections with “@Given”, “@Then” and “@When” are the sections gluing or connecting the step_definitions code with the feature file content, through RegEx.
  2. So whatever test cases are written in the feature file, are converted to actions via code in the java files in the step_definitions folder.
  3. Create another folder named as Cucumber_Test
    1. In this folder, create a java file as below with the content as displayed in the box named TestRunner.java.
    2. This java file will glue the feature file with the step definition file, using CucumberOptions tag.
    3. It can also be used to generate a html file displaying the result of the tests.
package cucumberTest;

import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(
features = "Feature" //Path of the feature folder
,glue={"step_definition"} //Path of the step_definitions folder
, format = { "pretty", "html:target/site/cucumber-pretty", "json:target/cucumber.json"} //path to create the results folder
, tags = { "~@ignore" }
)

public class TestRunner {
public static void main(String[] args)
{

}
}

Right click on feature folder to create feature file. The form to create a feature file will open, select the file to be created as feature file.
Create file with the extension as “.feature” and click on finish button.
Open the created feature file to edit it and write the test case in the Given, When & Then form
A java class will be created in the pageObjects and the step_definitions folder. Right click on the step_definitions folder and select the option to create a class. Name the class and click on the “Finish” button
Enter name for java class and click on the “Finish” button.
The class created in the step_definition can be editing and the code to test the test cases from the feature file can be written there.
It should contain the TestRunner.java class.
The TestRunner.java should contain the code as displayed to bind the feature files with the step_definitions package using RegEx.

5. How is the execution happening ?

  1. The TestRunner.java file is executed as a jUnit Test.
  2. It recognizes the feature files present by the extension as login.feature
  3. It executes the step_definition files, by reading the Given, When & Then statements, by matching using RegEx from the Feature files
  4. The tests are executed using a headless browser – PhantomJS.
    1. As most of these test cases are planned to be executed on a scheduled time, the need for a browser to be launched and viewing of execution is not required
    2. However, if the need arises of viewing the execution, even that can be changed by just replacing the driver of the browser to the best suited one
  5. The report of the test gets created in the target/site file and gets saved in an index.html file.
To execute the feature files, the TestRunner.java file needs to be executed as jUnit Test by right clicking the TestRunner.java class and select the option “jUnit Test” from options presented in “Run As”.
As we are using a headless browser – PhantomJS, log statements can be added to know how the flow of execution is going, when execution starts.
When the execution starts, then all the statements from the feature file are arranged in Tree Structure to display the passed cases and failed ones.
When a test case failes, its displayed like this.
When a test case passes, its displayed like this.

Following is an example of how the result for the same is displayed when a test is completed. Test cases that have passed get highlighted in green and the ones that fail get highlighted in red.

Tips related to Automation :

  1. Writing the programs in Page Object Model makes the code simpler and maintainable
  2. Write independent test cases
  3. Have dynamic data fed to the system, so results are more accurate
  4. Cucumber lets you reuse the same piece of step definition, provided the step in the feature file matches. So that code can be reused.