Top 5 Cucumber Best Practices for Selenium Automation

Do you know Cucumber is a great tool used to run acceptance tests using the plain-text functional descriptions with Gherkin? Behavior Driven Development strategy or BDD, as it is popularly known, is implemented using the Cucumber tool.

The best part about using the Cucumber BDD framework are:

Can't wait to get started with Cucumber? To help you out, we will be diving into some of the best Cucumber practices that will enable you to write better scenarios using the Gherkin language. You will also get a clearer picture of the Behavior Driven Development concepts with these practices.

Basics of Cucumber BDD Framework

Before we jump dive into Cucumber best practices, there are a few things you need to understand about the Cucumber BDD framework. First, to work with Cucumber for Selenium automation testing, you would need three types of files as described below:

In the next section of this blog, we will understand feature files in detail and how we can use them efficiently. These are some of the essential practices you should implement for successfully using Cucumber and Selenium. As already stated, we will use Gherkin to write the scenarios in the Cucumber BDD framework. Let us now understand in detail some Cucumber best practices.

1. Creating a Feature File

We will start by creating a file in our project structure that will consist of the steps to mimic a certain functionality. Since, in this post, we will understand Cucumber's best practices, we will only focus on how we can write our features file to model our test scenarios. We will see the practical implementation later. As an example, let us take the Login functionality using Gherkin.

Use Case: Model the behavior of logging into an application with valid credentials:

  1. Create a file with .feature extension inside the project folder. For example, let us name it "Login.feature".
  2. Inside the file, we will give a title depicting the functionality. So in our example, it can be something like "Feature: Login Action."
  3. We will now start writing our scenarios in the feature file. The general syntax for writing a scenario in a feature file is:
 
 As [a user]
 I want to [perform some action]
 for [ achieving a result]


So using the above two points, let us start with writing a Feature:

Feature: Login Action

Scenario: As an existing user, I want to log in successfully.

With this, you need to make a note of the important points listed below:

Next, in the feature file, you will be writing the Scenarios. Scenarios are simply the behavior of a functionality. While testing, we might have to write multiple scenarios to cover the test scope. To write a scenario, we use Keywords defined by Gherkin. The primary keywords used in Gherkin sentences are:

1. Given: Defines the pre-condition of the test.

2. When: Defines the user action that will be performed.

3. Then: Defines the post-condition or the outcome of the test.

4. But: Used to add negative conditions to the test.

5. And: Used to add a condition(s) to the test.

Note that you only need to state what you want to do in the feature file and not how you want to do it. The how part will be taken care of in the Step Definition file, which we will see later in this article.

See below an example of a poorly written scenario:

 
Scenario: As an existing user, I want to login successfully
Given the user is on the Home page
When the user navigates to the Login page
And the user can see the login form
And the user enters username and password
And the user is able to click on the Submit button 
Then the user is logged in successfully
And the successful login message is displayed


There is no point in writing such lengthy scenarios with unwanted details as it makes it difficult to read and maintain. A better way to write the same scenario with fewer lines is as follows:

 
Scenario: As an existing user, I want to login successfully.
Given the user is on the Home page
When the user navigates to the Login page
And the user enters username and password
Then the successful login message is displayed


Did you see how with fewer sentences, we can depict the same scenario by including only the necessary details and ignoring beating around the bush? :slightly_smiling_face:

Below are a few points that you need to keep in mind while writing scenarios in Gherkin:

2. Separating Feature Files

When testing with live applications, you might have to create multiple feature files. It becomes crucial to bifurcate the feature into different files. You can organize files so that all the features related to a specific functionality are grouped in a package or a directory. This is another one of the essential Cucumber best practices we recommend for seamless BDD implementation.

For example, consider an e-commerce application; you can organize the file such that, at the first level, you can have a package, say Orders, and in that, you can have multiple features like Pending Orders, Completed Orders, Wishlist, etc. Doing so will make your project organized, and it will be easy for you to locate the tests as per the functionality.

3. Using The Correct Perspective

At times it becomes very confusing as to what perspective should you write your scenarios in; the first person or third person. The official Cucumber BDD framework documentation uses both points of view. Below are the arguments for both the point of view:

First Person

BDD was created by Dan North, who, in his article "Introducing BDD," recommends the use of the first person. Using the first person is rational since it depicts keeping yourself in place of the person actually performing the action.

Third Person

The people who prefer the third-person point of view state that using the first-person can confuse the reader. It does not clarify who is performing the action, i.e., an individual user, an admin, or some user with a particular set of roles. It is argued that third-person usage shows the information formally and minimizes the risk of making any false assumptions about who is actually involved in performing/testing a scenario.

So, all in all, there is no mandate on using any one point of view; the one practice that you have to remember is to maintain consistency. The description should resonate with the test steps and be from a single perspective.

4. Additional Keywords Used in Gherkin

Apart from the commonly used keywords discussed above, there are a few more that are used in Gherkin. If you want to implement the Cucumber best practices, this is an important one to start practicing.

Background

Background simplifies adding the same steps to multiple scenarios in a given feature. This means if some common steps have to be executed for all the scenarios in a feature, you can write them under the Background keyword.

For example, to order a product from an e-commerce website, you will have to do the following steps:

  1. Open the website.
  2. Click on the Login link.
  3. Enter the username and password.
  4. Click on the Submit button.

Once you have completed the above steps, you can search for the product, add that product to your cart, and proceed with the checkout and payment. Since the above steps would be common for many functionalities in a feature, we can include them in the Background.

 
Feature:  Add To Cart

Background:
Given the user is on the Home page
And the user navigates to the Login page
And the user enters username and password
Then the successful login message is displayed


Always try to keep the background as short as possible since it will be difficult to understand the following scenario if it is kept lengthy. The key with the Cucumber Feature file is the shorter, the better.

Scenario Outline

A Scenario outline is similar to the test data corresponding to a test scenario. It is no compulsion to write a scenario with a scenario outline, but you can write it if needed.

 
Scenario outline: Order with different quantities

Given: User searches for HP Pen Drive
When: Add the first result on the page with quantity <qty>
Then: Cart should display <qty> pen drive


Examples:

 
|qty|
|1|
|5|
|24|


Doc Strings

If the information in a scenario does not fit in a single line, you can use DocString. It follows a step and is enclosed within three double quotes. Though often overlooked, it is one of the most crucial Cucumber best practices to follow.

 
Scenario: Login with a valid-user
Given the user is on the Home page
And the user navigates to the Login page
And the user enters username and password
Then the successful login message is displayed with text:

“You have successfully logged into your account! There are multiple discount offers 
waiting for you!!”


Data Table

The Data Table is quite similar to Scenario Outline. The main difference between the two is that the Scenario outline injects the data at the scenario level, while the data table is used to inject data at the step level.

 
Scenario: Login with a valid-user
Given the user is on the Home page
And the user navigates to the Login page
And the user enters <username> and <password>

| username | password |
| test1 | password1 |


As shown in the example above, you can use a data table in single steps with different data that you may need to inject.

Languages

Cucumber is not limited to writing the scenarios in English. Similar to the conventions followed in English, you can write the scenarios in multiple human languages. The official Cucumber documentation has all the information about using the Language feature and the dialect code of various languages.

For example, to use French as the language to write your scenarios, you can use the # language as a header in the functionality like below:

# language : fr 

(Note: fr is the dialect code for French)

Tags

There may be cases when you need not execute all the scenarios of the test. In such cases, you can group specific scenarios and execute them independently by using Tags. Tags are simply the annotations used to group scenarios and features. They are marked with @ followed by some notable text.

Examples:

 
@SmokeTest @RegressionTest
Scenario: ….

@End2End
Feature: ….


Note that the tags are inherited in the feature file by all the components, viz the scenario outline, scenario, etc. Similarly, if there is a tag on the Scenario Outline, the data examples will also inherit the tag.

The above examples can be configured for execution as shown below:

tags={“@End2End”} First, all the scenarios of the feature under @End2End tag would be executed.
tags={“@SmokeTest”} All the scenarios under @SmokeTest would be executed.
tags={“@SmokeTest , @RegressionTest”} This type of definition denotes OR condition hence, all the scenarios that are under @SmokeTest tag or @RegressionTest the tag would be executed.
tags={“@SmokeTest” , “@RegressionTest”} In such a definition, all the scenarios under the @SmokeTest AND @RegressionTest will be executed.
tags={~“@End2End”} All the scenarios under @End2End the tag will be ignored.
tags={“@SmokeTest , ~@RegressionTest”} All the scenarios under @SmokeTest the tag will be executed, but the scenarios under the @RegressionTest tag would be ignored.

Similar to the examples above, you can make combinations of tags as per your requirement and execute the scenarios/features selectively.

5. Step Definition(Step Implementation)

So far, we have only understood what our scenarios would do as part of Cucumber best practices. But the next and vital step to automate using Cucumber Selenium is adding a Step Definition that would do the how part, i.e., how would the scenario execute? When Cucumber runs a step in the Scenario, it refers to a matching Step Definition for execution.
Implementation of steps can be done in Ruby, C++, Javascript, or any other language, but we will use Java as our example.

If you are using an IDE that already has Gherkin and Cucumber installed, you will see suggestions to create a new .java file or select one which has the steps implemented already. On selecting any of the options, a method will be created in the class. For instance, we are resting the step definition for the below step:

Given the user is on Home Page.

A method would be generated automatically, with annotation having the header text the same as that of the step description:

 
@Given(“^the user is on Home Page$”)
public void homePage() throws Throwable{

//Java code to check the above description
….
…..
}


To create step implementation of scenarios that get data from Scenario Outline or Data Tables, the data is included in the annotations as regular expressions, along with passing as a parameter to the method.

 
@When(“^Add the first result on the page with quantity \”([0-9]+)”\$”)
public void addQuantity(int qty) throws Throwable{

//Java code to pass qty in the qty field
…
...

}


And that is how you can implement the steps that you write in the Feature file using Gherkin. Always remember the below points while implementing step definitions-

Wrapping Up

You are now familiar with some of the most important Cucumber best practices to follow with your BDD strategy or while implementing Cucumber and Selenium. To summarize this blog post, we would recommend you to:

Happy testing!

 

 

 

 

Top