Show / Hide Table of Contents

Writing test cases - Gherkin Approach (Java / Spring boot)

In this article we will show you how to write test cases using Gherkin approach. Gherkin approach is often used to test features in Behavior-Driven Development (for example: acceptance criteria of a user story) and in Agile environment. The test cases are represented by test scenarios written in gherkin language, and each sentence is implemented by code-behind. You can reuse the same sentence across the test project so the code-behind can also be reused.

With this method, testers (or business users) and automation engineers can work together: One can maintain the repository of test scenarios in Gherkin and the other can maintain automation implementations. When a scenario is not yet automated, it can still be served for manual execution.

Note

Gherkin approach is perfect for feature testing combined with BDD (Behavior-Driven Development).

But it may not be suitable for complex end-to-end tests. For this use cases, Gherkin scenarios may be too long, and the code-behind of each phrase may be difficult to maintain. For complex end-to-end tests, you may consider Keyword-driven/Data-driven testing approach.

Step 1: Prerequisites for Gherkin Approach

JDK 8, maven and lombok

Step 2: Create a simple maven project

Open pom.xml paste below code

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>fr.axa.automation.webengine</groupId>
  <artifactId>sample-gherkin-webengine-java</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>sample-gherkin-webengine-java</name>

  <properties>
    <maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
    <maven-surefire-plugin.version>3.0.0-M7</maven-surefire-plugin.version>
    <webengine-boot-gherkin.version>2.2.0</webengine-boot-gherkin.version>
  </properties>

  <dependencies>

    <dependency>
      <groupId>fr.axa.automation.webengine</groupId>
      <artifactId>webengine-boot-gherkin</artifactId>
      <version>${webengine-boot-gherkin.version}</version>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven-compiler-plugin.version}</version>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>${maven-surefire-plugin.version}</version>
      </plugin>

    </plugins>
  </build>
</project>

For your information, we use junit 5 with the framework

Step 3: Project structure

  • In Features folder, test scenarios written in Gherkin Language and saved in .features file.
  • In step, the implementation of these scenarios by code.
  • In model, the page model.
  • CucumberRunnerTest : Runner for executing tests

Step 4: Observe SUT and identify UI Elements

Observing system under test from Developer tools provided with browser. Here in our tutorial, we will operate 3 elements, to benefits the advantages of the Framework, we will put these 3 elements into a PageModel.

Step 3 UI Elements

This is exactly the same step we've discussed in Linear Script Approach. Please refer to Observe SUT and Identify UI Elements for more information.

Step 5: Write test scenarios (.feature)

Create a Feature file and name it sample-flow.feature, place it under the folder features Paste this below code :

Feature: Sample training

  Scenario: first-scenario
    Given I visit the test page
    When I choose the language with text "Français"
    And I want to buy a coffee
    And I click on the first next button
    Then I go to the next page

There is no limit how to write the scenario using the keywords given-when-then. But generally, people often use Given to specify the preconditions, When to specify actions and Then to specify expected results. Following the same naming convention across teams can ensure good understanding of scenarios for all stakeholders.

Step 6: Generate test steps from features

Once the feature is written, place the caret at a step in your .feature file and press Alt + Enter.

Name the java class: SampleFlowStep.java

It will automatically generate code to match each sentence:

package fr.axa.automation.feature.step;

import io.cucumber.java.en.And;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

public class SampleFlowStep {
@Given("I visit the test page")
public void iVisitTheTestPage() {
}

    @When("I choose the language with text {string}")
    public void iChooseTheLanguageWithText(String arg0) {
    }

    @And("I want to buy a coffee")
    public void iWantToBuyACoffee() {
    }

    @And("I click on the first next button")
    public void iClickOnTheFirstNextButton() {
    }

    @Then("I go to the next page")
    public void iGoToTheNextPage() {
    }
}

Step 5: Complete the code for using page model and browser factory

Create the page model :

package fr.axa.automation.feature.model;

import fr.axa.automation.webengine.core.AbstractPageModel;
import fr.axa.automation.webengine.core.WebElementDescription;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.experimental.FieldDefaults;
import org.openqa.selenium.WebDriver;


@FieldDefaults(level = AccessLevel.PUBLIC)
public class FirstPageModel extends AbstractPageModel {

    @Getter
    WebElementDescription language = WebElementDescription.builder().tagName("select").id("language").build();

    @Getter
    WebElementDescription coffeeRadio = WebElementDescription.builder().tagName("input").id("coffee").build();

    @Getter
    WebElementDescription teaRadio = WebElementDescription.builder().tagName("input").id("tea").build();

    @Getter
    WebElementDescription waterRadio = WebElementDescription.builder().tagName("input").id("water").build();

    @Getter
    WebElementDescription nextStep = WebElementDescription.builder().tagName("button").xPath(".//button[contains(text(),\"Next (3-second-delay)\")]").build();

    public FirstPageModel(WebDriver webDriver) throws Exception {
        populateDriver(webDriver);
    }
}

Complete the SampleFlowStep class

package fr.axa.automation.feature.step;

import fr.axa.automation.feature.model.FirstPageModel;
import fr.axa.automation.webengine.helper.WebdriverHelper;
import fr.axa.automation.webengine.step.AbstractStep;
import io.cucumber.java.en.And;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.experimental.FieldDefaults;
import org.openqa.selenium.WebDriver;

@Getter
@FieldDefaults(level = AccessLevel.PROTECTED)
public class SampleFlowStep extends AbstractStep {

    WebDriver driver;
    FirstPageModel firstPageModel;

    public SampleFlowStep() throws Exception {
        driver = WebdriverHelper.initializeDriver();
        firstPageModel = new FirstPageModel(driver);
    }

    @Given("^I visit the test page$")
    public void visitTheTestPage() throws InterruptedException {
        addInformation("Open WebEngine test page");
        driver.get("http://webengine-test.azurewebsites.net/Step1.html");
    }

    @And("^I choose the language with text \"([^\"]*)\"$")
    public void chooseTheLanguage(String language) throws Exception {
        addInformation("Choose the language");
        getFirstPageModel().getLanguage().selectByText(language);
    }

    @And("^I want to buy a coffee$")
    public void seePopUpAndEnterText() throws Exception {
        getFirstPageModel().getCoffeeRadio().click();
    }

    @And("^I click on the first next button$")
    public void clickFirstButtonOKInThePopup() throws Exception {
        getFirstPageModel().getNextStep().click();
    }

    @Then("^I go to the next page$")
    public void goToTheNextPage() {
        addInformation("Success");
        getDriver().close();
    }
}

Step 7: Create the runner class

package fr.axa.automation.feature;

import org.junit.platform.suite.api.ConfigurationParameter;
import org.junit.platform.suite.api.ConfigurationParameters;
import org.junit.platform.suite.api.IncludeEngines;
import org.junit.platform.suite.api.SelectClasspathResource;
import org.junit.platform.suite.api.Suite;

import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;

@Suite
@IncludeEngines("cucumber")
@SelectClasspathResource("features")
@ConfigurationParameters({
                            @ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "fr.axa.automation.feature.step"),
                            @ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty, html:target/report-gherkin/report.html, fr.axa.automation.webengine.listener.WebengineReportListener, json:target/cucumber-report/cucumber.json")
                        })
public class CucumberRunnerTest {

}

Step 6: Run test case

Run :

Result :

Note

The source code of this exercise can be found in our Github repository. Project Name: sample-gerkhin-webengine https://github.com/AxaFrance/webengine-java/sample-gerkhin-webengine

  • Edit this page
In this article
Back to top Copyright ® 2016-2024 AXA France, All rights reserved.