DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Architecting a Comprehensive Testing Framework for API and UI Testing
  • Cypress API Testing: A Detailed Guide
  • Which API Testing Strategy Should You Use? Manual vs. Automated
  • Cypress.io — The Rising Future of Web Automation Testing

Trending

  • The Developer's Guide to Context-Aware AI: When Your Code Documentation Becomes Intelligent
  • Agentic Testing: Moving Quality From Checkpoint to Control Layer
  • What Is Plagiarism? How to Avoid It and Cite Sources
  • Your API Authentication Isn’t Broken; It’s Quietly Failing in These 6 Ways
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. API Testing With Cucumber

API Testing With Cucumber

Testing APIs in a microservices environment can be a challenging task. In this tutorial, we will learn to address it in BDD-style testing using Cucumber.

By 
Randhir Singh user avatar
Randhir Singh
·
Sep. 25, 21 · Tutorial
Likes (5)
Comment
Save
Tweet
Share
15.1K Views

Join the DZone community and get the full member experience.

Join For Free

An API represents a set of rules that enables services to communicate with each other. It is important to have a shared understanding of the API by the stakeholders. Behavior Driven Development (BDD) allows us to describe behaviors that are understandable to domain experts, testers, and developers through examples. A well-written example serves to represent a balanced view of competing concerns -

  • Shared understanding. An example can be shared among API stakeholders to promote communication and understanding.
  • Tests.  Implement the example as an automated test to check the functionality of the API.
  • Documentation. An example can be used by anyone to understand the system.

BDD is a very apt tool to test APIs. We will use Cucumber that supports BDD to test APIs developed in Java. One advantage of doing so is that the Java developer who implemented the API does not have to learn a new language to test it.

Test Automation Project

We have to set up a Java Maven Project that contains our BDD scenarios that we are going to automate. Include the following dependencies.

  • Cucumber libraries to allow us to write BDD scenarios in Gherkin syntax
  • Cucumber Pico container for dependency injection
  • Rest Assured to test and validate REST calls
  • JSON to handle JSON documents
  • Apache Log4J to log requests and responses
  • JUnit to allow us to run BDD scenarios as JUnit test
XML
 
    <dependencies>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-core</artifactId>
            <version>6.6.0</version>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>6.6.0</version>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>gherkin</artifactId>
            <version>15.0.2</version>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-jvm-deps</artifactId>
            <version>1.0.6</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>6.6.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-picocontainer</artifactId>
            <version>6.11.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <version>4.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.14.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.14.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-iostreams</artifactId>
            <version>2.14.1</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20210307</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit-jupiter.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

Project Organization

The picture shows a sample project organization. It consists of the following folders under test.

  • Context - Contains utilities to hold context to help communication among steps
  • Microservice - Each microservice can have a folder to contain scenarios for API exposed by it. Within each microservice folder, create the following folders
    • features - Holds feature files
    • steps - Implements steps from feature files
    • dev/qa/prod - Environment variables for different environments where APIs are hosted
    • common - Implement steps common among features
  • Testrunner - Runner for Cucumber tests
  • Util - Contains utilities

Test automation

Gherkin Basics

Cucumber understands Gherkin, a structured natural language syntax based upon the Given/When/Then format. Gherkin allows us to write business readable API specifications that can also be used as automated tests. It is written in feature files which are plain text files with .feature extension.

Each feature file contains one or more scenarios. Each scenario is made up of one or more steps. Each step starts with one of five keywords: Given, When, Then, And, But. Given, When, Then introduce respectively the context, action, and outcome section of a scenario. And But are conjunctions that continue the preceding section. 

A sample test is shown below. A scenario should contain enough information to balance among its key features -  shared understanding, test, and documentation.

Gherkin
 
@Tag
Feature: Perform full demographic verification of a person

  Background:
    Given caller presents a valid access token

  Scenario: Perform full demographic verification with valid credentials
    Given a person with full demographic details
      | adhar_id            | 123456789        |
      | full_name           | John Doe         |
      | dob                 | 31/12/1990       |
      | phone_no            | 999999999999     |
      | email               | [email protected]     |
    And the match threshold is set to 1.0
    When request is submitted for full demographic verification
    Then verify that the HTTP response is 200
    And a transaction id is returned

Each step in the feature file needs to be implemented in Java. In the step definition below, we

  • Read the configuration for an environment
  • Make REST call using Rest Assured
  • Save the response of the call in the context for the benefit of other steps
Java
 
public class Microservice1Steps {

    private final World world;
    private final Properties envConfig;
    private RequestSpecification request;

    public Microservice1Steps(World world) {
        this.world = world;
        this.envConfig = World.envConfig;
        this.world.featureContext = World.threadLocal.get();
    }

    @Before
    public void setUp() {
        request = RequestSpecificationFactory.getInstance(world);
    }

    @Given("caller presents a valid access token")
    public void getOAuth2Token() {
        String grantType = envConfig.getProperty("microservice1-grant_type");
        String clientId = envConfig.getProperty("microservice1-client_id");
        String clientSecret = envConfig.getProperty("microservice1-client_secret");
        String accessTokenUrl = envConfig.getProperty("microservice1-access_token_url");

        String body = String.format("grant_type=%s&client_secret=%s&client_id=%s", grantType, clientSecret, clientId);

        RequestSpecification request = RequestSpecificationFactory.getInstanceOAuth2();

        Response response = request
                .accept(ContentType.URLENC)
                .body(body)
                .post(accessTokenUrl);

        String responseString = response.then().extract().asString();
        String accessToken = new JSONObject(responseString).getString("access_token");

        world.scenarioContext.put("accessToken", accessToken);
    }
}

A set of scenarios may be run as a JUnit test:

Shell
 
mvn test -Denv=local -Dcucumber.filter.tags="@Tag"

Tag selects a set of tests to run and -Denv selects the environment to run the tests on.

The complete project is available on my GitHub.

Conclusion

In this article, we learned why BDD is a natural fit for testing API as it enhances shared understanding, tests, and documentation of the API. For Java developers, a Maven project with Cucumber libraries is easy to set up to add scenarios and test them.

API Cucumber (software) Testing API testing file IO

Opinions expressed by DZone contributors are their own.

Related

  • Architecting a Comprehensive Testing Framework for API and UI Testing
  • Cypress API Testing: A Detailed Guide
  • Which API Testing Strategy Should You Use? Manual vs. Automated
  • Cypress.io — The Rising Future of Web Automation Testing

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook