Behavior Driven Development Tutorial : Selenium Testing With Gherkin
Tags: showdev, webdev, testing, tutorial
Published: 2022-08-17 11:42:00



Cucumber and Selenium are widely used frameworks for BDD(Behavior Driven Development) and browser automation respectively. Although on paper, it seems like a nice pair but when it comes to reality a lot of testers shy away from it. The major reason behind this is Gherkin as most testers hesitate to use it as it feels like an additional task since the test scripts are still to be written separately.

But this is not true for all. Using Gherkin can actually help in testing as it serves as a good document for all the features and can be written by anyone even with almost zero coding knowledge.

Clients say, *“Cucumber benefits us to understand the application code as it uses Gherkin language which is in Plain Text.”*

Being written in Gherkin, it acts as a bridge between various layers, PMs — Dev — Testers — Clients. Let us move towards understanding Behavior Driven Development with Gherkin and how it can make Selenium testing better.

In this article, I’ll further explore this topic on how to do Behavior Driven Development by Selenium testing with Gherkin. Before I start with Gherkin, I’d like to give you a small brief about [TDD vs BDD](https://www.lambdatest.com/selenium-grid-online?utm_source=devto&utm_medium=organic&utm_campaign=aug17_sd&utm_term=sd&utm_content=webpage).

## So, What Is Behavior Driven Development?

Behavior Driven Development or popularly known as BDD, is a widely used development approach in the software industry as it empowers its user to write cases in plain English language. This helps team members even with no technical know-how to understand what is going on in the project that closes the gap between business people and technical people

In addition to a low technicality and easier to understand approach, the main advantage of Behavior Driven Development is that it transpires from TDD ie. Test-Driven Development, which supports automated testing with multiple test data with minimum intervention in code.

Cucumber — A BDD Framework Tool: Behavior Driven Development is implemented with the help of [Cucumber framework](https://www.lambdatest.com/selenium-automation?utm_source=devto&utm_medium=organic&utm_campaign=aug17_sd&utm_term=sd&utm_content=webpage) which helps in automating the cases in a well-formatted and readable form.

Cucumber feature files: These files written in Gherkin language ending with .feature extension are an integral part of Cucumber and are used for application specifications.

## Getting Started With Gherkin For Selenium Testing

**Now that you know what Behavior Driven Development is let’s get started with Gherkin for Selenium Testing.**

Gherkin is a Business Readable, Domain Specific Language which entitles its users to write effective
tests in a well-documented way that requires the least reasoning and involved logic details.

Let us understand this with a Gherkin example.

“Buyers should not be able to fill invalid credit card details.”
Versus
“On the payment page, If a buyer enters a credit card number, that is not 16 digits of length, then when they try to proceed, it should give an error message pop up stating that the entered number is not correct.”

The first Gherkin example is unclear and vague in comparison to the second one. Vagueness leads to errors and makes it harder for the tester to understand the requirement and implement test cases.

## Gherkin Syntax For Selenium Testing

File structure in Gherkin is defined by the way different lines of code are indented in a feature file. Almost all lines in Gherkin for [Selenium](https://www.lambdatest.com/blog/automation-testing-with-selenium-cucumber-testng/?utm_source=devto&utm_medium=organic&utm_campaign=aug17_sd&utm_term=sd&utm_content=blog) Testing starts with a special keyword and line endings terminate statements which are called as steps.

A Gherkin feature file is a combination of features, scenarios, and steps which generally looks like this:

    Feature: Some terse yet descriptive text of what is desired  
     
    Background:Some common prerequisite setup applicable to all situations  
        Scenario: Some determinable business situation  
             Given some precondition  
             And some other precondition  
             When some action by the actor  
             And some other action  
             And yet another action  
             Then some testable outcome is achieved  
             And something else we can check happens too  
       
        Scenario: A different situation

When executing the feature, the trailing portion of each step (after keywords like Given, And, When, etc) is matched to a regular expression generally called as glue code and can be written in any language. In this tutorial, JAVA will be used for the same.

Let us now walkthrough the above example to understand all the keywords

### Feature

Feature keywords are used to donate a software feature. It usually contains a list of scenarios linked to that feature. Main elements of feature are :

* The keyword — Feature.

* The keyword, followed by the name user wants to give to the feature.

* An optional description that can span multiple lines i.e. all the text between the line containing the keyword Feature, and a line that starts with Scenario or Background which is optional

A good feature name should look something like :

*In order to meet some goal as a type of user I want a feature*

As a good Gherkin coding convention it is highly recommended that one feature makes up for one *.feature file which in term is named by replacing spaces with underscore and converting feature name to lowercase. Let’s take a Gherkin example,

*Feature : In order to learn Gherkin as a beginner I want to study this tutorial
Feature file name : in_order_to_learn_gherkin_as_a_beginner_i_want_to_study_this_tutorial.feature*

### Background

It is usually used to add some context steps that are common to all scenarios and needs to run before each scenario in a single feature file. It is like an untitled optional scenario

    Background : Given a customer named John  
        When clicks on buy now button  
        Then he should be redirected to payment page

### Scenario

Scenario makes the core of Gherkin structure. It describes the functionality that is under test. Main aim of a scenario is to be able to make the viewer understand what is being tested and how. The scenario keyword is followed by an optional title.

One or multiple scenarios makes up a feature file depending upon the feature in test and one or multiple steps makes up for a feature file.

By convention a good scenario follows following pattern

* Describe an initial context using keyword Given

* Describe an event using keyword When

* Describe an expected outcome using keyword Then

    Scenario : John wants to automate Selenium with Gherkin  
         Given John wants to learn Gherkin  
         When He starts reading this tutorial  
         Then he is able to write feature file

### Steps

Steps basically make up the part of a scenario by means of given, when, then.

### Given

The sole purpose of a Given statement is to give a context in order to establish a known state before the user starts interacting with the feature scenario under test.

### When

This is used to describe the event due to user actions in a given state.

### Then

The purpose of then step is to describe and analyse the outcomes. This analysis aims to add benefit to features by verifying the outcome that is or is not related to Given and When or may be to some external system.

### But

These keywords are used to combine several Given, When or Then statements helping to make the scenario to be more readable and presentable.

    Scenario : Understanding the steps  
          Given I establish a context  
          And I add another context  
          When I discuss them both  
          And I ask questions  
          Then I have no more doubts  
          But I have a better understanding

## How To Run Selenium Test Scripts Using Cucumber?

To make a gherkin project for Selenium Testing, the easiest way is to create a new maven project in any IDE like Eclipse. Also the dependencies for Cucumber, Selenium, and Junit runners to execute the feature files.

*for using Cucumber with java*

    <dependency>   
       <groupId>info.cukes</groupId>   
       <artifactId>Cucumber-java</artifactId>   
       <version>1.0.2</version>   
       <scope>test</scope>   
    </dependency>

*for Selenium*

    <dependency>   
       <groupId>org.Seleniumhq.Selenium</groupId>   
       <artifactId>Selenium-java</artifactId>   
       <version>2.47.1</version>   
    </dependency>

*For junit runner to run Cucumber features*

    <dependency>   
       <groupId>junit</groupId>   
       <artifactId>junit</artifactId>   
       <version>4.10</version>   
       <scope>test</scope>   
    </dependency>

## Why Use Gherkin With Selenium Testing?

Selenium is a widely used tool for functional testing across top organizations as it is easy to integrate with Gherkin and makes understanding and automating of the flow both easy and possible to be done at the same time.

By doing so one makes it easy to maintain test cases which also serves as proper documentation for all the Stakeholders and Analysts. Selenium is easy to integrate and a widely liked automation tool adds up to the usage of Cucumber. Together they make up a framework which is very easy to set up and has a low maintenance cost.

Moreover, the ability to run feature files parallelly is another advantage. Also, both Gherkin and Selenium can be coded in Java for writing the glue code for steps and browser automation respectively.

## Benefits Of Gherkin In Selenium Testing With Example

Here I will explain the usage of Gherkin for Selenium Testing with some examples and the framework along with file structure by means of the following example.

Let’s take a test scenario with the development of a web application for an organization, let’s say ’Shopping.com’, and the team is discussing a process flow of order placement by a customer.

First Step, for a customer to place an order, he/she should navigate to the website and login.

    Given Customer navigates to the website  
    And Customer login to his account

After that customer searches for a product and clicks on the Add to Cart button

    when a customer searches for laptop  
    And clicks on Add to Cart button

Customer reaches the cart page and is able to click place order button

    Then Customer is redirected to cart page  
    And Customer is able to click the place order button.

After the flow is passed on to the automation tester, he uses it to write automation cases. Further, he adds automation code steps for the discussion file by converting it to a feature file.

    Feature : Place new order  
       As a customer, I want to place an order for searched item  
          Scenario : Place an order for the required product  
                Given Customer navigates to the website  
                And Customer login to his account  
                When customer searches for laptop  
                And clicks on add to cart button  
                Then Customer is redirected to cart page  
                And Customer is able to click the place order button

Now to make these steps work I’ll write step definition code

    package Cucumber.stepDefinitions;  
       
    public class PlaceOrderStepDefs {  
          @Given(“Customer navigates to the website”)  
          public void navigateToWebsite(){  
          }  
          
          @And(“Customer login to his account”)  
          public void customerLogin(){  
          }        
          
          @When(“customer searches for laptop”)  
          public void searchForLaptop(){  
          }        
          
          @And(“clicks on add to cart button”)  
          public void clickAddToCart(){  
          }  
          
          @Then(“Customer is redirected to cart page”)  
          public void redirectionToCartPage(){  
          }  
          
          @And(“Customer is able to click the place order button”)  
          public void clickPlaceOrderButton(){  
          }  
    }

Now the point to note here is that there would be some data related to customers that are required and might be used by other feature files and scenarios as well. So it makes sense to create a separate file for such data called a properties file. Also, steps like loading this property file, initializing the driver, closing the browser after each scenario also need to be done and this would be common to all tests. So it makes sense to create a base steps file and inherit that to all step definition files.

    #  APP        
    url=http://www.shopping.com/   
       
    #  Selenium      
    webdriver.chrome.driver=resources/chromedriver  
       
    #  CUSTOMER      
       
    customerId=12345  
    customerUsername=steven  
    customerPassword=password123



    public class BaseTests {  
        public static WebDriver driver;  
        
          @BeforeClass  
          public static void initialiseDriverAndProperties() {  
                loadTestProperties();  
                driver = new ChromeDriver();  
                driver.manage().window().maximize();  
           }  
     
          @AfterClass  
          public static void closeBrowser() {  
                driver.quit();  
          }  
     
          private static void loadTestProperties(){  
                Properties properties = System.getProperties();  
                try {  
                      properties.load(  
                      new FileInputStream(new File("resources/test.properties")));  
                } catch(Exception ex) {  
                      ex.printStackTrace();  
                      System.exit(-1);  
                }  
          }  
    }

Having written BaseSteps.java and test.properties file now let us complete the step definition file

    package Cucumber.stepDefinitions;  
       
    public class PlaceOrderStepDefs extends BaseSteps{  
          @Given(“Customer navigates to the website”)  
          public void navigateToWebsite(){  
                driver.get(System.getProperty(“url”));  
          }  
     
          @And(“Customer login to his account”)  
          public void customerLogin(){
                driver.findElement(By.id(“username”)).enterData(“username”);  
                driver.findElement(By.id(“password”)).enterData(“password”);  
                driver.findElement(By.id(“login”)).click();  
          }  
     
          @When(“customer searches for laptop”)  
          public void searchForLaptop(){  
                driver.findElement(By.id(“searchBox”)).enterData(“Laptop”);  
                driver.findElement(By.id(“searchButton”)).click();  
          }  
     
          @And(“clicks on add to cart button”)  
          public void clickAddToCart(){  
                driver.findElement(By.id(“addToCart”)).click();  
          }  
     
          @Then(“Customer is redirected to cart page”)  
          public void redirectionToCartPage(){  
                Assert.assertTrue(driver.findElement(By.id(“cartPageHeader”)).isDisplayed());  
          }  
     
          @And(“Customer is able to click the place order button”)  
          public void clickPlaceOrderButton(){  
                Assert.assertTrue(driver.findElement(By.id(“placeOrderButton”)).isClickable());  
          }  
    }

Finally, step would be to a runner file to run this feature.

    package Cucumber;  
      
    @RunWith(Cucumber.class)  
    @CucumberOptions(  
          plugin = {"pretty"},  
          glue = {"Cucumber.stepDefinitions"},  
          features = {"src/test/java/Cucumber/features"})  
       
    public class CucumberTestRunner { 
    }

So with this example it is quite evident how easy it is to use Gherkin for Selenium Testing to make automation better.

## Using Gherkin For BDD On Online Selenium Grid

In order to execute the Selenium automation over an Online Selenium Grid, you just need to update the BaseSteps.java to have the LambdaTest account username and access token along with a few codes changes to let the system know that it will a RemoteWebDriver running on LambdaTest grid URL with these capabilities.

Here’s what updated BaseSteps.java would look like

    public class BaseTests {    
          
    public static RemoteWebDriver driver;    
          
          @BeforeClass    
          public static void initialiseDriverAndProperties() {    
                loadTestProperties();    
                DesiredCapabilities capabilities = new DesiredCapabilities();  
               
                String username = "<your_lambdatest_username>";  
                String accesskey = "<your_lambdatest_accesstoken>";  
                String lambdaTestGridURL = "@hub.lambdatest.com/wd/hub";  
                   
                capabilities.setCapability("build", "Selenium_Gherkin_Project");  
                capabilities.setCapability("name", "Placing order for a product");  
                capabilities.setCapability("platform", "Windows 10");  
                capabilities.setCapability("browserName", "chrome");  
                capabilities.setCapability("version", "73.0");  
                capabilities.setCapability("visual",false);    
                capabilities.setCapability("network",false);    
                capabilities.setCapability("console",false);    
                capabilities.setCapability("tunnel",false);  
                try {  
                      driver = new RemoteWebDriver(new URL("http://" + username + ":" + accesskey                     + lambdaTestGridURL), capabilities);  
                } catch (MalformedURLException e) {  
                      System.out.println("Invalid grid URL");  
                }   
          }    
           
          private static void loadTestProperties(){    
                Properties properties = System.getProperties();    
                try {    
                      properties.load(    
                      new FileInputStream(new File("resources/test.properties")));    
                } catch(Exception ex) {    
                      ex.printStackTrace();    
                }    
          }    
    }

Execute the test same as earlier using the TestRunner file and you are good to go with added advantages of using [Selenium grid](https://www.lambdatest.com/blog/tdd-vs-bdd/?utm_source=devto&utm_medium=organic&utm_campaign=aug17_sd&utm_term=sd&utm_content=blog) and get more information about the execution in a more presentable form.

***Click here if you want to know more about [automation testing tools](https://www.lambdatest.com/blog/automation-testing-tools/?utm_source=devto&utm_medium=organic&utm_campaign=aug17_sd&utm_term=sd&utm_content=blog)***

## Keeping A Track Of Test Results Using LambdaTest Dashboard

After you’ve completed the tests, you can further keep track of all your automation scripts using LambdaTest dashboard. Here in the Automation tab you can see the Timelines, Analytics, and Automation Log of all the tests you’ve run and the different builds used in the tests.

You can see all your tests under the Automation Log, here you can see the summary of your tests, any exceptions encountered, track commands, network and metadata. You can also create issues and share it with your team on the preferred Project Management tool.

![](https://cdn-images-1.medium.com/max/2710/0*3q9V8IZK8wlG5GQw.png)

***Click here if you want to know more about [automation testing platforms](https://www.lambdatest.com/automation-testing?utm_source=devto&utm_medium=organic&utm_campaign=aug17_sd&utm_term=sd&utm_content=webpage)***

## Using LambdaTest Platform For Cross Browser Test

You can even utilise LambdaTest platform to perform Cross Browser Testing over 2000+ real browsers & browser versions. On LambdaTest dashboard you get an overview of all the tests and activities done so far along with available integrations. You can see the number of tests run via automation by using real time browser utility, concurrent sessions, date of execution and much more.

![](https://cdn-images-1.medium.com/max/3200/0*MJpYjqVOi5EZBKxR.png)

![](https://cdn-images-1.medium.com/max/3200/0*vq49ma5scq8L5Gsl.png)

By using Realtime [Cross Browser Testing](https://www.lambdatest.com/) panel, you can execute tests on over 2000+ real browsers & browser versions by just simply selecting from the available list.

![](https://cdn-images-1.medium.com/max/3200/0*0KmrnwGgmR17AfQI.png)

In Visual UI Testing, users can compare screenshots on multiple combinations of OS and browser combinations.

![](https://cdn-images-1.medium.com/max/3200/0*Z9NLybPIVbYD_xN7.png)

It also provides features to test across different UI for responsiveness depending on different screen sizes and resolutions.

![](https://cdn-images-1.medium.com/max/3200/0*Edyvncxta2PWesP3.png)

You can even add issues or bugs at the same time when you encounter them and track them in the Issue Tracker.

![](https://cdn-images-1.medium.com/max/3200/0*lriSKdU0geGeeMWJ.png)

With integration on more than 30 bug tracking, CI/CD, Project Management tools you can share the bugs with your team on the go.

***Click here if you want to know about [test automation cloud](https://www.lambdatest.com/automation-testing?utm_source=devto&utm_medium=organic&utm_campaign=aug17_sd&utm_term=sd&utm_content=webpage).***

## Wrapping It Up

In this tutorial I explained how using BDD framework like Cucumber with Gherkin can help in better collaboration among all the stakeholders along with the basics of Gherkin language and how to use its syntax. Then I went on to develop our first Selenium test automation script using Gherkin for Selenium Testing.

Now you know why you shouldn’t shy away from Gherkin for Selenium Testing. Also, how it can help all the stakeholders in your team have a strong understanding of the project. Thereby helping the project achieve its business goals faster.

Happy Testing!!