Open Source For You

Starting the DevOps Journey Using Cucumber and Selenium

DevOps is a software building process which emphasises communication and collaboration between the teams involved in product management, software development, and operations. Cucumber is a behaviour driven development tool, which when combined with Selenium, a test recording and playback tool, improves the development team’s efficiency and productivity.

It is often said that continuous change is the law of the universe and the same is true in the software industry. We have seen a variety of software development models, starting from Waterfall, V and spiral models to the incremental option. All these models have different requirements and guidelines and suit different scenarios. These days, most organisations have embraced the Agile methodology for software development.

The Agile method of developing software and applications focuses on delivering high quality products frequently and consistently, which leads to an increase in business value and profits.

Table 1 lists the differences between the Waterfall and Agile software development approaches.

You can see that the Waterfall model can cause overshooting in time and resources, which can lead to huge losses to the company in terms of profits and user satisfaction. To avoid this, organisations have started adopting the Agile model. There are other reasons too, for choosing this model, some of which are listed below.

Figure 1: Agile and DevOps complement each other with the support of the QA and IT operations teams

Figure 2: Wall of confusion between the development and operations teams

Steps in the Agile approach

Let’s look at the steps involved in implementing the Agile methodology.

1. Discovery: To develop a high quality product, one needs to have a clear vision and considerable experience in the technology used in that project. Discovery sessions are significant, since they are the basis for all the upcoming activities in the sprint. During these sessions, the clients’ goals, the users’ expectations and the business challenges are understood deeply so that no ambiguity remains in the minds of the team, regarding the product.

2. Product backlog: The result of successful discovery sessions is product backlog, which contains a list of all the features that need to be developed. These features are then classified on the basis of priority by the product owner (in discussion with the client), so that high priority features can be developed, tested and delivered first.

3. Iterations: After the high-level product backlog is finalised along with the priority, sprints are planned and work begins on the features mentioned in the backlog.

Note: Every successive sprint in Agile is both iterative and incremental. It is iterative in the sense that it provides improvements based on the experience gained in the previous sprints, and incremental because it adds new features to the system.

4. Cycle: If all the features are completed and tested successfully, then the cycle stops; otherwise, additional sprints are planned to carry out the remaining work.

Agile and DevOps: The connection

Agile and DevOps – these two terms have become the buzzword these days. Though these two words are used interchangeably, there’s a stark difference between them. Agile is mainly concerned with software development and the processes or steps involved in it, whereas DevOps comes into the picture after a high quality product has been developed, i.e., it is about the deployment and management of software. The term DevOps is derived from two words – development and operations. Before delving deeper into the details of DevOps, let’s see how it emerged in the IT scene.

We have seen how organisations reaped benefits by implementing the Agile methodology, but this model also had some hitches, which are listed below:

Usually, whenever any product is released or any service is made live by an IT organisation, two departments come together to support this release – the development and operations teams. Yet, there is a lack of coordination between development activity and operations activity. The development team feels it is being paid to bring about ‘change’, whereas the operations team is looking at stability and considers ‘change’ its enemy. This conflict in mindsets often leads to inefficiency and overhead costs for the company. DevOps is a practice employed to smoothen the IT service delivery by promoting communication between development and operations teams, which is essential to increase a company’s productivity. It helps the company to continually deliver software with highly stable features, faster and more frequently.

DevOps brings more flexibility to the Agile methodology and leverages its productivity. It widens the scope of Agile principles by including operations teams in its ambit instead of stopping the Agile cycle at code check-in only. So, you can deduce that Agile principles and processes can be employed as a part of DevOps. In layman’s language, we can say that by using the Agile methodology, high-end products are developed and by implementing DevOps, the developed products are deployed in a timely manner. So the Agile model and DevOps complement each other, but are totally different from one another.

The need for DevOps in IT

We have seen how DevOps helps in reducing the friction between the development and operations teams. Now let’s see what effects DevOps has if it’s integrated into our software development process.

Figure 3: The file hierarchy in the project will look like this

Figure 4: Methods skeleton being generated by Cucumber by parsing the feature file

Behaviour driven development (BDD)

We have just discussed the Agile model and DevOps, and the need to implement these in today’s software development scenario. But since DevOps involves various teams such as developers, testers, stakeholders, etc, sometimes there can be a lack of communication between them too. Developers can misinterpret the needs of business stakeholders, and testers can misunderstand the ideas of developers. This can cause a huge negative impact on the overall productivity of the team, affecting actual deliverables. So there is a need for a common language to drive the team and bridge the communication gap. In addition, the following disadvantages were observed in Agile projects:

These weaknesses in the Agile model led to the birth of behaviour driven development (BDD). BDD is also an Agile software development process, which encourages effective communication between the business team, developers, project managers and QA by increasing the focus on business goals and business values. It was conceived by Dan North in 2003 who defines it as follows: “BDD is a second-generation, outside-in, pull-based, multiple-stakeholder, multiple-scale, high-automation, Agile methodology. It describes a cycle of interactions with well-defined outputs, resulting in the delivery of working, tested software that matters.”

BDD is an extension of TDD with a few minor differences such as:

1. Tests in BDD are written in plain English.

2. Tests are more behaviour focused and deal with the functionality of the application.

3. BDD uses extensive examples.

BDD has a lot of advantages over the traditional TDD approach. A few of these have been listed below.

BDD testing tools

There are various tools available in the market, which support the BDD framework. Some of these are Cucumber, Specflow, Behave, JBehave, JBehave Web, Lettuce, Behat, Kahlan, etc.

Cucumber: Cucumber is the most widely used open source tool that supports behaviour driven development. It allows you to write application behaviour in a simple, English-like language known as Gherkin. It is written in Ruby but can support various languages like Java, JS, Python, .NET, C++, etc. Due to its wide language support, it can integrate with almost all testing tools and frameworks. You can read more about this tool at https://cucumber.io/docs.

Gherkin: Gherkin is a language that Cucumber understands. It is defined on GitHub as, “… a business readable, domain-specific language that lets you describe the software’s behaviour without detailing how that behaviour is implemented.” Gherkin is easy to learn and understand by non-programmers, but allows illustration of business rules in real-world domains. It has a particular syntax that contains keywords such as scenario, given, then, and, examples, but, etc. A sample Gherkin document looks like what’s shown below:

Feature: Refund item

Scenario: Jeff returns a faulty microwave

Given Jeff has bought a microwave for $100

And he has a receipt

When he returns the microwave

Then Jeff should be refunded $100

So you can see that we have specified the behaviour of the ‘Refund item’ system using various keywords underlined above in plain English text. You can study Gherkin and its various rules at https://cucumber.io/docs/reference.

Figure 5: Output of the script depicting one scenario and five steps being passed

Figure 6: Complete release pipeline with CI/CD tools implemented

Configuring Cucumber with Selenium

Now, let’s look at how we can integrate Cucumber with Selenium for automated testing in DevOps.

The prerequisites are any IDE (I will be taking Eclipse Neon for tutorial purposes) and the latest Java installed on your system.

Jars required: The following jars/drivers need to be downloaded before starting with the configuration:

After all the required files have been downloaded, follow the steps given below.

1. Launch Eclipse and create a Java project named ‘CucumberSelenium’ in it.

2. Create three packages under the src folder named cucumberTest, resources.Files and testScripts, which will each contain the runner file, test case feature file and the step definition file.

Feature file: This file will contain our test case written in Gherkin language and will have the feature extension.

Runner file: Our Cucumber-Selenium framework will not have the Main method since we will be using JUnit to run our Java class. So this Java class will be run as a JUnit test to run our script.

Note: Each feature file will have its separate runner class in this framework.

Step definition file: We have designed our feature file and runner file, but how will Cucumber get to know what code to execute for the specific test step mentioned in the feature file? This is taken care of by a separate Java class called step definition file.

3. Now create the CucumberRunner.java class under the cucumberTest package, testCase.feature file under the resources.Files package and TestCase.java class under the stepDefinition package.

4. Next, copy the following in your runner class and feature file.

For CucumberRunner.java, copy:

package cucumberTest;

import org.junit.runner.RunWith;

import cucumber.api.CucumberOptions;

import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)

@CucumberOptions(

features = “src/resources/Files/testCase.feature”,

glue = {“stepDefinition”},

tags = {“@cucumber”}

)

public class CucumberRunner {

}

For testCase.feature, copy:

Feature:To check functionality of google search page

@cucumber

Scenario Outline:

Given <required> browser is opened

When <url> is opened

And <keyword> is searched in search box

Then the first link in search results should be opened

And browser is closed

Examples:

| required | url | keyword |

| “chrome” | “http://www.google.com” | “DevOps” |

5. Now run your runner file as a JUnit test, and you can see the empty methods being auto generated in the console output of Eclipse for each test step in the feature file. The significance of these methods is that Cucumber reads test steps from your feature file and searches for the corresponding method in the package mentioned in the glue option of the runner file. The variable values are also passed as arguments to the methods, to make use of them while scripting. So you can see how beautifully Cucumber has taken care of every minute detail while designing this framework.

6. Now copy the following code in the step definition file TestCase.java:

package stepDefinition;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.chrome.ChromeDriver;

import cucumber.api.java.en.Given;

import cucumber.api.java.en.Then;

import cucumber.api.java.en.When;

public class TestCase {

WebDriver driver = null;

@Given(“^\”([^\”]*)\” browser is opened$”)

public void browser_is_opened(String arg1) throws Throwable {

if(arg1.equals(“chrome”)) {

System.setProperty(“webdriver.chrome.driver”, “D:\\Selenium\\chromedriver.exe”); // file path of driver where it is stored.

driver = new ChromeDriver();

driver.manage().window().maximize();

driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);

}

}

@When(“^\”([^\”]*)\” is opened$”)

public void is_opened(String arg1) throws Throwable {

driver.get(arg1);

}

@When(“^\”([^\”]*)\” is searched in search box$”)

public void is_searched_in_search_box(String arg1) throws Throwable {

driver.findElement(By.id(“lst-ib”)).sendKeys(arg1);

driver.findElement(By.xpath(“//*[@id=’tsf’]/div[2]/div[3]/center/input[1]”)).click();

}

@Then(“^the first link in search results should be opened$”)

public void the_first_link_in_search_results_should_be_opened() throws Throwable {

driver.findElement(By.xpath(“.//*[@id=’rso’]/div[3]/div/div[1]/div/div/h3/a”)).click();

}

@Then(“^browser is closed$”)

public void browser_is_closed() throws Throwable {

driver.close();

}

}

7. Since we have defined the code, run the runner file and the corresponding steps will be performed according to the defined test case.

8. Once execution is complete, you can see the execution status of the steps and scenarios in the console as shown in Figure 5.

So you can see how easily Cucumber can be configured with Selenium Web driver to implement the BDD framework. Using this framework, you can start your DevOps journey in the testing field, within your organisation.

CI/CD tools and DevOps

This framework can also be integrated smoothly with continuous integration and continuous delivery (CI/CD) tools like Jenkins, TeamCity, Bamboo, etc, so that automated tests can be run every time developers check their code into a central repository; reports can then be published to the required stakeholders as and when required.

So we have discussed the shift from the Waterfall model to the Agile model as well as the simultaneous implementation of DevOps and the Agile methodology. Try this BDD inspired framework using Selenium to leverage your team’s productivity and efficiency.