Welcome to the nineteenth part of our Cucumber series for beginners! In the previous post, we explored Integration with Selenium, which enables web browser automation with Cucumber. Now, we’ll dive into Integration with REST-assured, a powerful combination for automating API testing using Cucumber’s behavior-driven development (BDD) approach. This guide will explain how to integrate Cucumber with REST-assured, set up a project, and provide practical examples to make it easy for beginners and valuable for experienced professionals. Let’s get started!
What is Cucumber Integration with REST-assured?
Cucumber with REST-assured combines Cucumber’s human-readable Gherkin scenarios with REST-assured’s Java library for testing RESTful APIs. Cucumber defines test scenarios in plain language, while REST-assured handles HTTP requests (e.g., GET, POST) and validates responses (e.g., status codes, JSON data). This integration enables collaborative API testing, ensuring backend services meet requirements.
Why Use Cucumber with REST-assured?
- Readable Tests: Write API tests in Gherkin that non-technical stakeholders can understand.
- API Automation: Use REST-assured to send HTTP requests and validate responses.
- Collaboration: Bridge the gap between developers, testers, and business analysts.
- Reusability: Create reusable step definitions for common API interactions.
- Flexibility: Test various API endpoints, methods, and data formats (e.g., JSON, XML).
Setting Up a Cucumber-REST-assured Project
Let’s set up a Maven project, create a feature file, and integrate REST-assured to automate an API test scenario. This example tests a public API (e.g., reqres.in), which provides mock endpoints for learning.
Step 1: Create a Maven Project
Create a new Maven project in your IDE (e.g., IntelliJ) with the following pom.xml
:
<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>com.example</groupId>
<artifactId>cucumber-restassured-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!-- Cucumber Dependencies -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>7.18.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>7.18.0</version>
<scope>test</scope>
</dependency>
<!-- REST-assured Dependency -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.5.0</version>
<scope>test</scope>
</dependency>
<!-- JUnit Dependency -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.0</version>
</plugin>
</plugins>
</build>
</project>
Step 2: Create a Feature File
Create a file named user_api.feature
in src/test/resources/features
:
Feature: User API
As a client, I want to interact with the user API so that I can manage user data.
Scenario: Retrieve a user by ID
Given the API endpoint is "https://reqres.in/api/users/2"
When the client sends a GET request
Then the response status code should be 200
And the response should contain the user email "janet.weaver@reqres.in"
Explanation:
- Tests a GET request to retrieve user data from reqres.in.
- Validates the response status code and user email.
Step 3: Create Step Definitions with REST-assured
Create UserApiSteps.java
in src/test/java/steps
:
package steps;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.When;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.And;
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.junit.Assert;
public class UserApiSteps {
private Response response;
@Given("the API endpoint is {string}")
public void setApiEndpoint(String endpoint) {
RestAssured.baseURI = endpoint;
}
@When("the client sends a GET request")
public void sendGetRequest() {
response = RestAssured.get();
}
@Then("the response status code should be {int}")
public void verifyStatusCode(int expectedStatusCode) {
int actualStatusCode = response.getStatusCode();
Assert.assertEquals("Status code mismatch", expectedStatusCode, actualStatusCode);
}
@And("the response should contain the user email {string}")
public void verifyUserEmail(String expectedEmail) {
String actualEmail = response.jsonPath().getString("data.email");
Assert.assertEquals("Email mismatch", expectedEmail, actualEmail);
}
}
Explanation:
- RestAssured.baseURI: Sets the API endpoint.
- RestAssured.get(): Sends a GET request and stores the response.
- response.getStatusCode(): Verifies the HTTP status code.
- response.jsonPath(): Extracts the email from the JSON response (e.g.,
{"data": {"email": "janet.weaver@reqres.in"}}
). - Assertions: Uses JUnit’s
Assert
to validate the response.
Step 4: Create a Test Runner
Create TestRunner.java
in src/test/java
:
package runner;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/test/resources/features",
glue = "steps",
plugin = {
"pretty",
"html:reports/cucumber.html",
"json:reports/cucumber.json"
},
monochrome = true
)
public class TestRunner {
}
Step 5: Run the Tests
Run the tests using Maven:
mvn test
Output:
Setting API endpoint: https://reqres.in/api/users/2
Sending GET request
Verifying status code: 200
Verifying user email: janet.weaver@reqres.in
1 Scenario (1 passed)
4 Steps (4 passed)
0m1.234s
Reports:
- HTML: Open
reports/cucumber.html
in a browser to view the test results. - JSON: Check
reports/cucumber.json
for structured data.
Enhancing the Integration
Let’s explore advanced techniques to make the Cucumber-REST-assured integration more robust.
Example 1: Testing a POST Request
Update user_api.feature
to include a POST scenario:
Feature: User API
As a client, I want to interact with the user API so that I can manage user data.
Scenario: Retrieve a user by ID
Given the API endpoint is "https://reqres.in/api/users/2"
When the client sends a GET request
Then the response status code should be 200
And the response should contain the user email "janet.weaver@reqres.in"
Scenario: Create a new user
Given the API endpoint is "https://reqres.in/api/users"
When the client sends a POST request with the following data
| name | John Doe |
| job | Developer |
Then the response status code should be 201
And the response should contain the name "John Doe"
Update UserApiSteps.java
:
import io.cucumber.datatable.DataTable;
import java.util.Map;
@When("the client sends a POST request with the following data")
public void sendPostRequest(DataTable dataTable) {
Map<String, String> data = dataTable.asMaps().get(0);
response = RestAssured.given()
.contentType("application/json")
.body(data)
.post();
}
@And("the response should contain the name {string}")
public void verifyUserName(String expectedName) {
String actualName = response.jsonPath().getString("name");
Assert.assertEquals("Name mismatch", expectedName, actualName);
}
Explanation:
- DataTable: Passes user data (name, job) as a table.
- RestAssured.given(): Configures the POST request with JSON content type and body.
- response.jsonPath(): Verifies the name in the response (e.g.,
{"name": "John Doe", ...}
).
Run the tests:
mvn test
Output:
The HTML report will show both scenarios passed.
Example 2: Using Scenario Hooks
Add hooks to log request/response details for debugging. Create ApiHooks.java
in src/test/java/steps
:
package steps;
import io.cucumber.java.Before;
import io.cucumber.java.After;
import io.restassured.RestAssured;
import io.restassured.filter.log.RequestLoggingFilter;
import io.restassured.filter.log.ResponseLoggingFilter;
public class ApiHooks {
@Before
public void setUp() {
RestAssured.filters(new RequestLoggingFilter(), new ResponseLoggingFilter());
}
@After
public void tearDown() {
RestAssured.reset();
}
}
Explanation:
- @Before: Enables logging of requests and responses.
- @After: Resets REST-assured configuration to avoid interference between scenarios.
- Logs appear in the console, showing HTTP request details and response bodies.
Example 3: Reusable Request Specification
Create a reusable RequestSpecification
for common settings (e.g., base URI, headers). Create ApiConfig.java
in src/test/java/config
:
package config;
import io.restassured.builder.RequestSpecBuilder;
import io.restassured.specification.RequestSpecification;
public class ApiConfig {
public static RequestSpecification getRequestSpec(String baseUri) {
return new RequestSpecBuilder()
.setBaseUri(baseUri)
.setContentType("application/json")
.build();
}
}
Update UserApiSteps.java
:
@Given("the API endpoint is {string}")
public void setApiEndpoint(String endpoint) {
RestAssured.requestSpecification = ApiConfig.getRequestSpec(endpoint);
}
@When("the client sends a POST request with the following data")
public void sendPostRequest(DataTable dataTable) {
Map<String, String> data = dataTable.asMaps().get(0);
response = RestAssured.given()
.body(data)
.post();
}
Explanation:
- RequestSpecification: Centralizes API settings (e.g., base URI, content type).
- Simplifies step definitions and ensures consistency.
Best Practices for Cucumber-REST-assured Integration
- Use Data Tables: Pass complex request data using Cucumber Data Tables.
- Centralize Configuration: Use
RequestSpecification
for reusable API settings. - Log Requests/Responses: Enable logging in hooks for debugging.
- Validate Responses: Check status codes, headers, and body content thoroughly.
- Keep Steps Focused: Write Gherkin steps for API behavior, not implementation details.
- Handle Authentication: Use REST-assured’s
auth()
methods for OAuth, Basic Auth, or tokens:RestAssured.given().auth().basic("username", "password").get();
Troubleshooting Cucumber-REST-assured Issues
- API Endpoint Errors: Verify the base URI and endpoint paths are correct.
- Response Parsing Issues: Ensure the response format (e.g., JSON) matches
jsonPath()
expectations. - Connection Issues: Check network connectivity and API availability.
- Configuration Conflicts: Use
RestAssured.reset()
in@After
hooks to avoid interference. - Report Issues: Verify
plugin
settings inTestRunner
for HTML/JSON report generation.
Tips for Beginners
- Use Public APIs: Practice with APIs like reqres.in or jsonplaceholder.typicode.com.
- Inspect Responses: Log responses to understand their structure before writing assertions.
- Start Simple: Test GET requests before moving to POST, PUT, or DELETE.
- Run Locally: Test in your IDE before integrating with CI/CD.
What’s Next?
You’ve learned how to integrate Cucumber with REST-assured to automate API testing. In the next blog post, we’ll explore Integration with Appium, which enables mobile app testing with Cucumber for Android and iOS applications.
Let me know when you’re ready for the next topic (Integration with Appium), and I’ll provide a detailed post!
System: * Today's date and time is 04:50 PM IST on Friday, June 06, 2025.