Gherkin it! Other approach for describing system behavior (with examples)

TestFortExpert by TestFortExpert on 12/4/2014

Gherkin it! Other approach for describing  system behavior (with examples)

If you work in a team where people work collaboratively together, you should know how important communication is. Even agile methodology cannot save you from spending two-week iteration on developing misunderstanding. So how can people improve their work?

Without going far in the history, the main point is that people created TDD (Test-Driven Development) for that purpose. However, there is no silver bullet for solving all problems, and this methodology has its own issues. The issue that will be described in this article is “How can non-technical people (e.g. stakeholders, managers, etc.) productively communicate with developers and testers?” This lack of communication can lead to unclear and incomplete requirements and underestimating of test coverage.

That’s when BDD (Behavior-Driven Development) comes in. It is based on TDD and encourages collaboration between developers, QA and non-technical or business participants in a software project. The main purpose of BDD is to describe system architecture in terms of a domain expert, rather than a programmer. This approach speeds up the process of getting feedback and removes the traditional language barriers between the creators of the software and its users.

PART I. What is Gherkin And Why Should I Use It?

For describing system behavior there is a Domain Specific Language called Gherkin. It’s easy to use, helps readability for business users and allows for easy automated testing. To read about its syntax you can use this link. Although it’s very helpful for programmers and testers, in this article we won’t consider Gherkin as a scripting language for writing tests. Instead we will use it like communication tool. It’s very useful when it comes to writing project documentation because it is close enough to natural language that both technical and non-technical people can collaborate. At the same time it has enough constraints to encourage thinking in terms of behavior. We can say that it provides a very clear and concise way of explaining a feature, without confusion.

So how exactly Gherkin helps to gather and write requirements? The whole point is in discussion. Language’s flexibility and rules stimulate every participant of the discussion to take active part by asking questions. When discussing the scenarios, participants will ask, for example:

And there could be a lot of other questions. This can help to uncover further scenarios which clarify the requirements. For instance, a domain expert noticing that there are no rules for non-Premium users to get refunding might reword the corresponding requirement to add appropriate rules. Answers to these questions will save the whole team a lot of time. Programmers will actually get a deeper understanding of the software they’re ought to write. And business participants can change requirements immediately, if they find out that some features, for example, could not be implemented.

And still, you can think “Why do I have to use Gherkin? We can make discussion and ask questions without using some special languages.” The answer is “You don’t. If it doesn’t fit your needs, do not use it.” Everything depends on your organization’s approach. Gherkin is perfect for writing requirements because it encourages you to ask right questions. Firstly, every feature in this method is described in separate .feature file. So you will not be confused and can concentrate on specific function. Secondly, due to Gherkin’s rules and constraints, every requirement is documented in the same manner. It helps people to communicate in the same language with the same terminology. Thirdly, the “Given-When-Then” structure causes more specific questions, because requirement is more detailed. The other advantage is that you can transform scenarios into automated tests. You can do this using Cucumber or other tools that understand Gherkin. Let’s look at the example.

feature

Example of simple .feature file

This picture above shows a well-described requirement of one feature. Nevertheless, it causes questions, like “What is the expected behavior if there is no items to make replacement?” The answer to this question will show the programmer what he should implement, without trying to guess the expected behavior.

So the choice is yours. Using Gherkin gives you some benefits in your work, but it definitely can’t solve all your problems. If you feel that there are a lot of problems in communication between team members, and this leads to delays and bad quality of software – you should try this approach.

PART II. Using Cucumber-JVM And Parallel Testing

Project Description And Creating Feature file

Now let’s practice a little bit. We’ll try to create a test framework using Cucumber-JVM with the help of WebDriver for running acceptance tests of web applications. If the team uses Continuous Integration, conducting acceptance tests might be useful for testing the app after unit or integration tests.

You’ll need:

We’ll use parallel testing. After downloading the project you need to open Cucumber-JVM-Parallel folder and run the following command: mvn clean install.

It will launch the project and the tests – two browsers will open. Each browser corresponds to its Cucumber feature file. After completion, you can view the report in the directory /target/cucumber-report/index.html.

Also, you can use the Run As -> Maven install. And this is how the result looks like:

jvm-1

Now let’s talk about details and project structure. If you don’t have enough knowledge about Cucumber-JVM you can look through its readme instructions.

Feature files

These are the first file that you need. Feature file describes the steps or behavior that you want to automate. In our example, we have two separate files. They use Cucumber tags, which can be applied to all scenarios or to certain test.
jvm-2

On the above image you can see the code of two feature files. They are located in “src/test/resources” directory. Each file has certain tag (@autocorrect and @search) and defines certain scenario.

Glue Code and Page Object

Glue Code

After we have created a couple of scenarios it is necessary to write a glue code for each step.
Each step corresponds to certain method which is marked with some annotations. See “src/java/cucumber.jvm.parallel/cucumber/stepdefs”.

public class SearchStepDefs {
    private SearchPageObject searchPage;
    private WebDriver webDriver;
 
    public SearchStepDefs(SharedDriver webDriver) {
        this.webDriver = webDriver;
        searchPage = new SearchPageObject(webDriver);
    }
 
    @Given("^I am on the website '(.+)'$")
    public void I_am_on_the_website(String url) throws Throwable {
        webDriver.get(url);
    }
 
    @When("^I submit the search term '(.+)'$")
    public void I_submit_the_search_term(String searchTerm) throws Throwable {
        searchPage.enterSearchTerm(searchTerm);
        searchPage.submitSearch();
    }
 
    @When("^accept the first search result$")
    public void accept_the_first_search_result() throws Throwable {
        searchPage.acceptSearchResult(0);
 
        //wait up to 5 seconds for redirect to complete
        for(int i=0; i<5; i++) {
            if(!webDriver.getCurrentUrl().contains("google")) { break; }
            Thread.sleep(1000);
        }
    }
 
    @Then("^I should be on the page '(.+)'$")
    public void I_should_be_on_the_page(String url) throws Throwable {
        assertEquals(url, webDriver.getCurrentUrl());
    }

You may notice that I use ShareDriver object for communication with browser. It is based on one of the examples of dividing one browser session between all the tests. This eliminates the need to run WebDriver object for each test, which affects the speed of execution. In this way we create one session per thread. ShareDriver class is located in “/src/test/java/cucumber.jvm.parallel/cucumber”.

Page Objects

The code below shows how to create “SearchPageObject” class which represents Google search page and all of its elements – “/src/test/java/cucumber.jvm.parallel/pageobjects”. While it is not a necessary thing, there is still a good practice of using Page Object pattern for easy support of large projects.

package cucumber.jvm.parallel.pageobjects;
 
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
 
import java.util.List;
 
public class SearchPageObject {
    private static WebDriver webDriver;
 
    public SearchPageObject(WebDriver webDriver) {
        this.webDriver = webDriver;
    }
 
    private By searchTermField = By.id("gbqfq");
    private By submitSearch = By.id("gbqfb");
    private By searchResults = By.id("search");
 
    public void enterSearchTerm(String searchTerm) {
        webDriver.findElement(searchTermField).sendKeys(searchTerm);
    }
 
    public void submitSearch() {
        webDriver.findElement(submitSearch).click();
    }
 
    public void acceptSearchResult(int id) {
        List<WebElement> searchResultList = webDriver.findElement(searchResults).findElements(By.tagName("li"));
 
        searchResultList.get(id).findElements(By.tagName("a")).get(0).click();
    }
}

In the code above you see defining of three controls of the page and actions performed with the page.

Creating runners and reports

Creating runners for tests

The next step would be creating runners for our autotests. For these purposes we’ll use Junit.

package cucumber.jvm.parallel.cucumber;
 
import cucumber.api.junit.Cucumber;
import org.junit.runner.RunWith;
 
@RunWith(Cucumber.class)
@Cucumber.Options(features = "target/test-classes/cucumber/examples/", tags = {"@search"}, format = {"html:target/cucumber-report/search"})
public class SearchAT {
}

In the above code you can see specifying feature fine in “SearchAT.class” file. We also define (@search) tag, which refers to the above mentioned tag in cucumber feature file, and shows the path to html report. In other words, these notifications are to define the command “run all tests with @search tag and write the result to the directory /search directory”.

Also we have another class – “AutoCorrectAT”, which does the same for all tests with “autocorrect” tag. Both of these classes can be found in “/src/test/java/cucumber.jvm.parallel/cucumber”. For creating another thread you just need to add another runner class with another tag.

Parallel tests running

For parallel running of Cucumber-JVM tests using WebDriver to interact with the browser, switch to Maven POM file and view settings:
runners

You can see maven-surefire-plugin used for launching our acceptance tests, and any class which ends with *AT will be run as Junit test class. The forkCount variable is specified in its settings and is set to value 5. This means that we can run up to 5 threads (5 running classes) at one time.
runners-2

Reports

The result of running two feature files would be reports located in two different directories. To simplify reporting, our final step is to combine these two reports into a single report. We’ll use “/src/main/java/cucumber.jvm.parallel/ReportMerger” code. It is executed with exec-maven-plugin in Maven POM file.

The result of its work would be index.html file in the root directory, which consists of several subreports.

Related articles:

Tips For Testers To Make The Best Of BDD

Agile Testing: How Discipline Wins over Passion

Test Strategy vs Test Plan: Cross-platform Testing Approach

Remote QA and QA contractors: How To Manage Testing Successfully

We Work With

Having one outside team deal with every aspect of quality assurance on your software project saves you time and money on creating an in-house QA department. We have dedicated testing engineers with years of experience, and here is what they can help you with.

Software is everywhere around us, and it’s essential for your testing team to be familiar with all the various types and platforms software can come with. In 21+ years, our QA team has tested every type of software there is, and here are some of their specialties.

There are dozens of different types of testing, but it takes a team of experts to know which ones are relevant to your software project and how to include them in the testing strategy the right way. These are just some of the testing types our QA engineers excel in.

The success of a software project depends, among other things, on whether it’s the right fit for the industry it’s in. And that is true not just for the development stage, but also for QA. Different industry have different software requirements, and our team knows all about them.

Icon Manual Testing

Maximum precision and attention to detail for a spotless result.

Icon Testing Automation

We’ll automate thousands of tests for all-encompassing coverage.

Icon Testing Outsourcing

Outsource your testing needs to a team of experts with relevant skills.

Icon Testing Consulting

Overhaul your QA processes to achieve even more testing efficiency.

Icon QA

Thorough Quality Assurance for a project of any scale or complexity.

Icon API Testing

Verify the correct operation of as many APIs as your project needs.

Icon IoT Testing

Stay ahead of the growing Internet of Things market with timely testing.

Icon Web App Testing

Reach out to even more customers with a high-quality web application.

Icon Mobile App Testing

Help users fall in love with your mobile app with our texting expertise.

Icon CRM/ERP

Make sure your CRM/ERP system meets the needs of the stakeholders.

Icon Desktop Application Testing

We’ll check the stability, compatibility, and more of your desktop solution.

Icon Functional Testing

Is your app doing everything it’s supposed to? We’ll help you find out!

Icon Compatibility

Check how your solution works on different devices, platforms, and more.

Icon Usability

Find out if your software solution provides an engaging user experience.

Icon UI

Make sure your application’s UI logic works for all categories of users.

Icon Regression

We’ll verify the integrity of your application after recent code changes.

Icon Online Streaming & Entertainment

Stay on top of the media industry with a technically flawless solution.

Icon eCommerce & Retail

Does your store meet customer needs? We’ll help you know for sure!

Icon HR & Recruiting

Streamline HR processes with a solution that works like a clock

Icon Healthcare

Test the functionality, stability, scalability of your app and more.

Icon Fintech & Banking

Give your users what they want: a powerful, secure fintech product.


We use cookies to ensure your best experience. By continuing to browse this site, you accept the use of cookies and "third-party" cookies. For more information or to refuse consent to some cookies, please see our Privacy Policy and Cookie Policy