
REST Assured Tutorial: Complete Beginner’s Guide (2026)
REST Assured Tutorial: The Complete Beginner’s Guide (2026)
If you just Googled “how to test APIs in Java” and landed here — you are in exactly the right place.
This REST Assured tutorial will take you from zero — no setup, no prior API testing experience — to writing real, working API tests that you can run today. Every step is explained the way a senior engineer would explain it to a junior on their first day, not the way a documentation page explains it to someone who already knows everything.
By the end of this REST Assured tutorial you will have:
- REST Assured fully installed and configured on your machine
- Your first API test running and passing
- A solid understanding of every core concept you need for real projects
- The confidence to walk into any API testing interview and answer questions with actual experience behind you
Let’s build that foundation right now.
Table of Contents
- What is REST Assured and Why Should You Learn It?
- What is an API — Explained Simply
- Prerequisites — What You Need Before Starting
- Step-by-Step Installation and Setup
- Setting Up IntelliJ IDEA and Maven Project
- Maven Dependencies — Complete pom.xml
- Your First REST Assured Test
- Understanding the given() when() then() Structure
- HTTP Methods Explained with REST Assured Examples
- Working with Request Parameters
- Working with Headers and Authentication
- Validating Responses — Status, Body, Headers
- Extracting Values from Responses
- Logging Requests and Responses
- Common Beginner Errors and How to Fix Them
- Running Tests from Command Line
- REST Assured Best Practices for Beginners
- What to Learn Next
1. What is REST Assured and Why Should You Learn It?
REST Assured is an open-source Java library that makes testing REST APIs simple, readable, and powerful. It was created by Johan Haleby and is maintained by the REST Assured community on GitHub. Today it is the most widely used API testing library in the Java ecosystem — used by thousands of companies including large enterprises across India, the US, and Europe.
Before REST Assured existed, testing an API in Java looked like this:
java
// The old painful way — without REST Assured
URL url = new URL("https://reqres.in/api/users/2");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "application/json");
int responseCode = connection.getResponseCode();
BufferedReader reader = new BufferedReader(
new InputStreamReader(connection.getInputStream())
);
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
// Now manually parse the JSON... another 20 lines
// Now validate... another 10 lines
// Total: 50+ lines for one simple GET requestWith REST Assured, the same test is three lines:
java
// The REST Assured way
given()
.when()
.get("https://reqres.in/api/users/2")
.then()
.statusCode(200);That is the power of this REST Assured tutorial — by the end, you will write tests that are readable, maintainable, and professional in a fraction of the time.
Why REST Assured Specifically?
There are other API testing tools — Postman, Karate, HTTPClient. Here is why REST Assured is worth learning first:
It is Java — if your company uses Java for development or automation, REST Assured fits naturally into the existing stack. No context switching, no new language.
It is code — unlike Postman’s GUI, REST Assured tests live in your codebase. They are version controlled in Git, run in CI/CD pipelines, and reviewed in pull requests like any other code.
It is the interview standard — virtually every QA automation interview in 2026 includes REST Assured questions. Learning it makes you immediately more employable. If you want to prepare for those interviews specifically, read our REST Assured Interview Questions guide after completing this tutorial.
It scales — from a single test to a 500-test framework, REST Assured handles it with the same syntax.
2. What is an API — Explained Simply
Before diving into the REST Assured tutorial setup, you need a clear mental model of what you are actually testing.
An API (Application Programming Interface) is a way for two software applications to talk to each other. Think of it like a waiter in a restaurant:
- You (the client) tell the waiter (the API) what you want
- The waiter takes your request to the kitchen (the server)
- The kitchen prepares the response
- The waiter brings it back to you
In web applications, this conversation happens over HTTP using four main operations, commonly called CRUD:
| Operation | HTTP Method | What it does | Restaurant analogy |
|---|---|---|---|
| Create | POST | Creates a new resource | Placing a new order |
| Read | GET | Retrieves existing data | Asking what’s on the menu |
| Update | PUT / PATCH | Updates existing data | Changing your order |
| Delete | DELETE | Removes a resource | Cancelling your order |
What Does an API Request Look Like?
Every HTTP request has these parts:
Method: GET
URL: https://reqres.in/api/users/2
Headers: Content-Type: application/json
Authorization: Bearer abc123
Body: (empty for GET, JSON for POST/PUT)And every response comes back with:
Status Code: 200
Headers: Content-Type: application/json
Body: {
"data": {
"id": 2,
"email": "janet.weaver@reqres.in",
"first_name": "Janet",
"last_name": "Weaver"
}
}REST Assured’s entire job is to help you send these requests and validate these responses easily. Now that you understand what we are testing, let us set it up.
3. Prerequisites — What You Need Before Starting
This REST Assured tutorial assumes the following are already on your machine:
Java JDK 11 or Higher
REST Assured 5.x requires Java 11+. Check your Java version:
bash
java -version
You should see something like:
openjdk version "17.0.9" 2023-10-17
If not, download JDK 17 from Adoptium — it is free and the most widely used JDK in enterprise environments.
Maven 3.6+
Maven is the build tool that manages your project dependencies. Check:
bash
mvn -version
If not installed, download from maven.apache.org and follow the installation guide for your OS.
IntelliJ IDEA (Community Edition is Free)
Download from jetbrains.com/idea. The Community Edition is completely free and sufficient for this entire REST Assured tutorial.
That’s It
You do not need to install REST Assured separately. Maven downloads it automatically when you add it to your project. This is one of the great advantages of working in the Java ecosystem.
4. Step-by-Step Installation and Setup
REST Assured is added to your project through Maven dependencies — there is no installer to run, no PATH variable to configure. Here is the complete setup process.
Step 1 — Verify Java Installation
bash
java -version javac -version
Both should return version 11 or higher. If javac is not found, you have the JRE but not the JDK. Download the full JDK.
Step 2 — Verify Maven Installation
bash
mvn -version
Expected output:
Apache Maven 3.9.5 Maven home: /usr/local/Cellar/maven/3.9.5/libexec Java version: 17.0.9
Step 3 — Set JAVA_HOME (if not already set)
On Windows:
System Properties → Environment Variables → New Variable name: JAVA_HOME Variable value: C:\Program Files\Java\jdk-17
On Mac/Linux:
bash
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home export PATH=$JAVA_HOME/bin:$PATH
Add this to your ~/.bashrc or ~/.zshrc to make it permanent.
Step 4 — Create Your Maven Project
You will do this in IntelliJ in the next section. The Maven dependencies are what install REST Assured — no separate download needed.
5. Setting Up IntelliJ IDEA and Maven Project
Create a New Maven Project
- Open IntelliJ IDEA
- Click New Project
- Select Maven from the left panel
- Choose your JDK (17 recommended)
- Click Next
- Fill in project details:
- GroupId:
com.qatribe - ArtifactId:
rest-assured-tutorial - Version:
1.0-SNAPSHOT
- GroupId:
- Click Finish
IntelliJ creates this structure:
rest-assured-tutorial/ ├── src/ │ ├── main/ │ │ └── java/ │ └── test/ │ └── java/ └── pom.xml
All your REST Assured tests will live in src/test/java/. The pom.xml is where you add the dependencies.
Create the Test Package Structure
Right-click on src/test/java → New → Package:
com.qatribe.tests
This is where all your test classes will go. Good project structure from day one prevents headaches later.
6. Maven Dependencies — Complete pom.xml
This is the most important setup step. Replace the contents of your pom.xml with this complete configuration:
xml
<?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>com.qatribe</groupId>
<artifactId>rest-assured-tutorial</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<rest-assured.version>5.4.0</rest-assured.version>
<testng.version>7.9.0</testng.version>
<jackson.version>2.16.1</jackson.version>
</properties>
<dependencies>
<!-- REST Assured Core — the main library -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>${rest-assured.version}</version>
<scope>test</scope>
</dependency>
<!-- JSON Path — for navigating JSON responses -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-path</artifactId>
<version>${rest-assured.version}</version>
</dependency>
<!-- XML Path — for navigating XML responses -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>xml-path</artifactId>
<version>${rest-assured.version}</version>
</dependency>
<!-- JSON Schema Validator — for contract testing -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-schema-validator</artifactId>
<version>${rest-assured.version}</version>
</dependency>
<!-- TestNG — test execution framework -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
<!-- Jackson — for POJO serialization/deserialization -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- Hamcrest — for assertions (usually included with REST Assured) -->
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Maven Surefire — for running TestNG tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
</project>After saving, IntelliJ will show a Maven sync notification — click Load Maven Changes or Reload All Maven Projects. Maven will download all dependencies automatically. This takes 1–2 minutes on the first run.
What Each Dependency Does
rest-assured — the core library. Everything starts here.
json-path — lets you navigate JSON like response.jsonPath().getString("data.first_name"). Essential for response validation.
xml-path — same as json-path but for XML responses.
json-schema-validator — validates that your API response matches a predefined JSON schema. Used in advanced testing.
testng — the test runner. Provides @Test, @BeforeMethod, @AfterSuite annotations and test execution management.
jackson-databind — converts Java objects to JSON and back. Used when you want to send request bodies as POJOs instead of raw strings.
hamcrest — provides the assertion matchers like equalTo(), hasItem(), greaterThan() used inside then() blocks.
7. Your First REST Assured Test
Now the fun part. Let us write your first actual test.
We will use reqres.in — a free public API designed specifically for testing. No registration, no API key, no setup needed.
Create Your First Test Class
Right-click on src/test/java/com/qatribe/tests → New → Java Class → Name it FirstApiTest
java
package com.qatribe.tests;
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class FirstApiTest {
@BeforeClass
public void setup() {
// Set the base URI once — all tests in this class use it
RestAssured.baseURI = "https://reqres.in";
}
@Test
public void test_GetUser_StatusCode200() {
given()
.when()
.get("/api/users/2")
.then()
.statusCode(200);
}
@Test
public void test_GetUser_FirstNameIsJanet() {
given()
.when()
.get("/api/users/2")
.then()
.statusCode(200)
.body("data.first_name", equalTo("Janet"));
}
@Test
public void test_GetUser_EmailNotNull() {
given()
.when()
.get("/api/users/2")
.then()
.statusCode(200)
.body("data.email", notNullValue());
}
@Test
public void test_GetNonExistentUser_Returns404() {
given()
.when()
.get("/api/users/999")
.then()
.statusCode(404);
}
}Run the Test
Right-click anywhere in the class → Run ‘FirstApiTest’
You should see:
=============================================== Default Suite Total tests run: 4, Passes: 4, Failures: 0, Skips: 0 ===============================================
Congratulations — you just ran your first REST Assured tests.
What Just Happened?
Let us break down test_GetUser_FirstNameIsJanet() line by line:
java
given() // Start the request setup phase
.when() // Define what action to take
.get("/api/users/2") // Send a GET request to this endpoint
.then() // Start the validation phase
.statusCode(200) // Assert the status code is 200
.body("data.first_name", equalTo("Janet")); // Assert this JSON field equals "Janet"The JSON response from the API looks like this:
json
{
"data": {
"id": 2,
"email": "janet.weaver@reqres.in",
"first_name": "Janet",
"last_name": "Weaver",
"avatar": "https://reqres.in/img/faces/2-image.jpg"
}
}When you write body("data.first_name", equalTo("Janet")), REST Assured navigates the JSON path data → first_name and checks if the value equals "Janet". This navigation syntax is called JsonPath.
8. Understanding the given() when() then() Structure
This is the most fundamental concept in this entire REST Assured tutorial. Every test you ever write follows this exact pattern.
REST Assured follows BDD (Behavior Driven Development) syntax — the same structure used in Cucumber with Gherkin. This makes tests readable by both technical and non-technical team members.
The Three Phases
given() → SETUP → What conditions exist before the action? when() → ACTION → What action are we performing? then() → ASSERTION → What should be true after the action?
Everything That Goes in given()
java
given()
// Headers
.header("Authorization", "Bearer token123")
.header("Accept", "application/json")
.contentType("application/json")
// Parameters
.queryParam("page", 2)
.queryParam("per_page", 10)
.pathParam("userId", 5)
// Request body
.body("{ \"name\": \"Ajit\" }")
// Authentication
.auth().basic("username", "password")
// Base URI override
.baseUri("https://different-api.com")
// Logging
.log().all()Everything That Goes in when()
java
.when()
.get("/api/users") // GET request
.post("/api/users") // POST request
.put("/api/users/2") // PUT request
.patch("/api/users/2") // PATCH request
.delete("/api/users/2") // DELETE requestEverything That Goes in then()
java
.then()
// Status code
.statusCode(200)
// Response body
.body("data.id", equalTo(2))
.body("data.first_name", equalTo("Janet"))
.body("data", notNullValue())
.body("data.size()", greaterThan(0))
// Headers
.header("Content-Type", containsString("application/json"))
// Response time
.time(lessThan(3000L))
// Content type
.contentType("application/json")
// Logging
.log().ifError()A Complete Example Using Everything
java
given()
.header("Authorization", "Bearer token123")
.contentType("application/json")
.queryParam("page", 1)
.log().all()
.when()
.get("/api/users")
.then()
.log().ifError()
.statusCode(200)
.contentType("application/json")
.body("page", equalTo(1))
.body("data.size()", greaterThan(0))
.body("data[0].email", notNullValue())
.time(lessThan(3000L));9. HTTP Methods Explained with REST Assured Examples
Every API operation maps to an HTTP method. This REST Assured tutorial covers all five you will encounter in real projects.
GET — Retrieve Data
Use GET to read existing resources. GET requests never have a body and never modify data on the server.
java
@Test
public void test_GetAllUsers() {
given()
.queryParam("page", 1)
.when()
.get("https://reqres.in/api/users")
.then()
.statusCode(200)
.body("data.size()", greaterThan(0))
.body("page", equalTo(1))
.body("total", notNullValue());
}
@Test
public void test_GetSingleUser() {
given()
.pathParam("id", 2)
.when()
.get("https://reqres.in/api/users/{id}")
.then()
.statusCode(200)
.body("data.id", equalTo(2))
.body("data.first_name", equalTo("Janet"));
}POST — Create a New Resource
Use POST to create something new. POST requests always include a body. The expected status is usually 201 Created.
java
@Test
public void test_CreateUser() {
String requestBody = "{\n" +
" \"name\": \"Ajit Marathe\",\n" +
" \"job\": \"QA Lead\"\n" +
"}";
given()
.contentType("application/json")
.body(requestBody)
.when()
.post("https://reqres.in/api/users")
.then()
.statusCode(201)
.body("name", equalTo("Ajit Marathe"))
.body("job", equalTo("QA Lead"))
.body("id", notNullValue())
.body("createdAt", notNullValue());
}PUT — Full Update
Use PUT to replace an entire resource. All fields must be included — any missing fields are deleted.
java
@Test
public void test_UpdateUser_FullReplace() {
String requestBody = "{\n" +
" \"name\": \"Ajit Marathe\",\n" +
" \"job\": \"Senior SDET\"\n" +
"}";
given()
.contentType("application/json")
.body(requestBody)
.when()
.put("https://reqres.in/api/users/2")
.then()
.statusCode(200)
.body("name", equalTo("Ajit Marathe"))
.body("job", equalTo("Senior SDET"))
.body("updatedAt", notNullValue());
}PATCH — Partial Update
Use PATCH to update specific fields only. Other fields remain unchanged.
java
@Test
public void test_UpdateUser_PartialUpdate() {
// Only updating the job — name stays unchanged
String requestBody = "{ \"job\": \"QA Architect\" }";
given()
.contentType("application/json")
.body(requestBody)
.when()
.patch("https://reqres.in/api/users/2")
.then()
.statusCode(200)
.body("job", equalTo("QA Architect"))
.body("updatedAt", notNullValue());
}DELETE — Remove a Resource
Use DELETE to remove a resource. Successful deletion usually returns 204 No Content — no response body.
java
@Test
public void test_DeleteUser() {
given()
.when()
.delete("https://reqres.in/api/users/2")
.then()
.statusCode(204);
}10. Working with Request Parameters
Parameters are how you customise API requests. There are three types and it is important to know when to use each.
Query Parameters
Query parameters are appended to the URL after a ?. Use them for filtering, sorting, searching, and pagination.
URL with query params: https://reqres.in/api/users?page=2&per_page=5
java
@Test
public void test_PaginationWithQueryParams() {
given()
.queryParam("page", 2)
.queryParam("per_page", 3)
.when()
.get("https://reqres.in/api/users")
.then()
.statusCode(200)
.body("page", equalTo(2))
.body("per_page", equalTo(3))
.body("data.size()", equalTo(3));
}
// Multiple query params using Map
@Test
public void test_QueryParamsWithMap() {
Map<String, Object> params = new HashMap<>();
params.put("page", 1);
params.put("per_page", 6);
given()
.queryParams(params)
.when()
.get("https://reqres.in/api/users")
.then()
.statusCode(200);
}Path Parameters
Path parameters are dynamic values embedded directly in the URL path. Use them to identify specific resources.
URL with path param: https://reqres.in/api/users/2
↑ this is the path paramjava
@Test
public void test_PathParameter() {
int userId = 3;
given()
.pathParam("id", userId)
.when()
.get("https://reqres.in/api/users/{id}")
.then()
.statusCode(200)
.body("data.id", equalTo(userId));
}
// Multiple path parameters
@Test
public void test_MultiplePathParams() {
given()
.pathParam("resource", "users")
.pathParam("id", 2)
.when()
.get("https://reqres.in/api/{resource}/{id}")
.then()
.statusCode(200);
}Form Parameters
Form parameters are used when submitting form data (not JSON). Common in login endpoints.
java
@Test
public void test_FormParameters() {
given()
.contentType("application/x-www-form-urlencoded")
.formParam("username", "testuser")
.formParam("password", "testpass")
.when()
.post("https://api.example.com/login")
.then()
.statusCode(200);
}11. Working with Headers and Authentication
Adding Request Headers
Headers carry metadata about your request — content type, authentication, language preference, custom tracking IDs.
java
@Test
public void test_WithCustomHeaders() {
given()
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.header("X-Request-ID", "req-12345")
.header("X-Client-Version", "2.0")
.when()
.get("https://reqres.in/api/users/2")
.then()
.statusCode(200);
}
// Adding multiple headers using Headers object
@Test
public void test_WithHeadersObject() {
Headers headers = new Headers(
new Header("Content-Type", "application/json"),
new Header("Accept", "application/json"),
new Header("Authorization", "Bearer token123")
);
given()
.headers(headers)
.when()
.get("https://reqres.in/api/users/2")
.then()
.statusCode(200);
}Validating Response Headers
java
@Test
public void test_ValidateResponseHeaders() {
given()
.when()
.get("https://reqres.in/api/users/2")
.then()
.statusCode(200)
.header("Content-Type", containsString("application/json"))
.header("Server", notNullValue());
}Authentication in REST Assured
Basic Authentication
java
@Test
public void test_BasicAuth() {
given()
.auth().basic("username", "password")
.when()
.get("https://api.example.com/protected")
.then()
.statusCode(200);
}
// Preemptive — sends credentials without waiting for 401 challenge
given()
.auth().preemptive().basic("username", "password")
.when()
.get("https://api.example.com/protected");Bearer Token Authentication
java
String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";
given()
.header("Authorization", "Bearer " + token)
.when()
.get("https://reqres.in/api/users/2")
.then()
.statusCode(200);Extracting Token from Login Response
java
@Test
public void test_LoginAndUseToken() {
// Step 1: Login and extract token
String token =
given()
.contentType("application/json")
.body("{ \"email\": \"eve.holt@reqres.in\", \"password\": \"cityslicka\" }")
.when()
.post("https://reqres.in/api/login")
.then()
.statusCode(200)
.extract()
.path("token");
System.out.println("Token extracted: " + token);
// Step 2: Use token in authenticated request
given()
.header("Authorization", "Bearer " + token)
.when()
.get("https://reqres.in/api/users/2")
.then()
.statusCode(200);
}12. Validating Responses — Status, Body, Headers
Validation is the heart of every API test. REST Assured uses Hamcrest matchers for expressive, readable assertions.
Status Code Validation
java
// Exact status code
.then().statusCode(200);
.then().statusCode(201);
.then().statusCode(404);
// Using Hamcrest for flexibility
.then().statusCode(anyOf(is(200), is(201)));
.then().statusCode(not(500));
// Status line validation
.then().statusLine("HTTP/1.1 200 OK");Response Body Validation
java
// Single field
.then().body("data.first_name", equalTo("Janet"));
// Nested field
.then().body("data.address.city", equalTo("Mumbai"));
// Not null
.then().body("data.email", notNullValue());
// String operations
.then().body("data.email", containsString("@reqres.in"));
.then().body("data.first_name", startsWith("Jan"));
.then().body("data.last_name", endsWith("ver"));
// Numeric comparisons
.then().body("total", greaterThan(0));
.then().body("per_page", lessThanOrEqualTo(12));
.then().body("page", equalTo(1));
// Array/List validation
.then().body("data.size()", equalTo(6));
.then().body("data.first_name", hasItem("Janet"));
.then().body("data.id", hasItems(1, 2, 3));
// Multiple assertions chained
.then()
.statusCode(200)
.body("data.id", equalTo(2))
.body("data.first_name", equalTo("Janet"))
.body("data.email", containsString("reqres.in"))
.body("data.avatar", notNullValue());Response Time Validation
java
// Must respond within 3 seconds .then().time(lessThan(3000L)); // Must take at least 100ms (for rate limiting checks) .then().time(greaterThan(100L));
Content Type Validation
java
.then().contentType("application/json");
.then().contentType(ContentType.JSON);
.then().contentType(containsString("application/json"));13. Extracting Values from Responses
Extracting values from responses is essential when you need to reuse data across multiple API calls — for example, extracting a created user’s ID to use in a follow-up GET or DELETE request.
Method 1 — extract().path()
java
String firstName =
given()
.when()
.get("https://reqres.in/api/users/2")
.then()
.statusCode(200)
.extract()
.path("data.first_name");
System.out.println("First name: " + firstName); // JanetMethod 2 — Store the Response Object
java
Response response =
given()
.when()
.get("https://reqres.in/api/users/2")
.then()
.statusCode(200)
.extract()
.response();
// Extract multiple values from one response object
String firstName = response.path("data.first_name");
String lastName = response.path("data.last_name");
String email = response.path("data.email");
int id = response.path("data.id");
System.out.println(firstName + " " + lastName); // Janet WeaverMethod 3 — jsonPath()
java
Response response = get("https://reqres.in/api/users");
// Extract a list
List<String> allFirstNames = response.jsonPath().getList("data.first_name");
System.out.println(allFirstNames); // [George, Janet, Emma, ...]
// Extract specific item from list
String secondUserName = response.jsonPath().getString("data[1].first_name");
// Extract using GPath filter (advanced — great for interviews)
String user = response.jsonPath().getString("data.find { it.id == 2 }.first_name");Chaining API Calls with Extracted Values
java
@Test
public void test_CreateThenDeleteUser() {
// Step 1: Create user and capture ID
String userId =
given()
.contentType("application/json")
.body("{ \"name\": \"Test User\", \"job\": \"QA\" }")
.when()
.post("https://reqres.in/api/users")
.then()
.statusCode(201)
.extract()
.path("id");
System.out.println("Created user with ID: " + userId);
// Step 2: Delete the created user using extracted ID
given()
.pathParam("id", userId)
.when()
.delete("https://reqres.in/api/users/{id}")
.then()
.statusCode(204);
System.out.println("User deleted successfully");
}14. Logging Requests and Responses
Logging is your best friend when tests fail, especially in CI/CD pipelines where you cannot set breakpoints or debug interactively.
Log Everything
java
given()
.log().all() // Logs method, URI, headers, body, params
.when()
.get("https://reqres.in/api/users/2")
.then()
.log().all() // Logs status code, headers, body
.statusCode(200);Output:
Request method: GET
Request URI: https://reqres.in/api/users/2
Request params: <none>
Query params: <none>
Form params: <none>
Path params: <none>
Headers: Accept=*/*
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"data": {
"id": 2,
"email": "janet.weaver@reqres.in",
"first_name": "Janet",
"last_name": "Weaver"
}
}Log Only on Failure (Recommended for Production)
java
given()
.log().ifValidationFails()
.when()
.get("https://reqres.in/api/users/2")
.then()
.log().ifValidationFails()
.statusCode(200);This keeps CI/CD logs clean — only prints when a test fails.
Selective Logging
java
given()
.log().headers() // Only log request headers
.log().params() // Only log request parameters
.log().body() // Only log request body
.log().method() // Only log HTTP method
.log().uri() // Only log the URI
.when()
.get("https://reqres.in/api/users/2")
.then()
.log().status() // Only log response status
.log().headers() // Only log response headers
.log().body() // Only log response body
.statusCode(200);Global Logging for All Tests
java
// In your BaseTest @BeforeSuite
RestAssured.filters(
new RequestLoggingFilter(),
new ResponseLoggingFilter()
);15. Common Beginner Errors and How to Fix Them
This section saves you hours of debugging. These are the exact errors every beginner hits in their first week.
Error 1: NoClassDefFoundError or ClassNotFoundException
Symptom:
java.lang.NoClassDefFoundError: io/restassured/RestAssured
Cause: REST Assured dependency not properly loaded in Maven.
Fix:
- Check your
pom.xmlhas the correct dependency - Right-click
pom.xml→ Maven → Reload Project - File → Invalidate Caches and Restart (IntelliJ)
Error 2: Connection Refused
Symptom:
java.net.ConnectException: Connection refused
Cause: Wrong URL, wrong port, or the API server is down.
Fix:
- Test the URL in your browser first
- Check
RestAssured.baseURIis set correctly - Check you are not missing
https://vshttp://
Error 3: SSL Certificate Error
Symptom:
javax.net.ssl.SSLHandshakeException: PKIX path building failed
Cause: The API server has a self-signed or expired SSL certificate.
Fix (for testing environments only):
java
RestAssured.useRelaxedHTTPSValidation(); // or per request: given().relaxedHTTPSValidation()
Never use this for production API testing.
Error 4: 401 Unauthorized
Symptom:
java.lang.AssertionError: 1 expectation failed. Expected status code <200> but was <401>.
Cause: Missing or incorrect authentication.
Fix:
java
// Check you are adding auth correctly
given()
.header("Authorization", "Bearer " + validToken)
// OR
given()
.auth().basic("username", "password")Error 5: JSON Parsing Error
Symptom:
com.jayway.jsonpath.PathNotFoundException: No results for path: $['data']['first_name']
Cause: Wrong JSON path — the field name or nesting is incorrect.
Fix:
java
// Add this to see the actual response body
.then()
.log().body() // See what the actual JSON looks like
.statusCode(200);Then adjust your path to match the actual structure.
Error 6: Import Issues — Cannot Find Symbol
Symptom:
error: cannot find symbol given() ^
Cause: Missing static imports.
Fix: Add these at the top of every REST Assured test class:
java
import static io.restassured.RestAssured.*; import static org.hamcrest.Matchers.*;
Error 7: 415 Unsupported Media Type
Symptom:
Expected status code <200> but was <415>.
Cause: Missing or wrong Content-Type header on POST/PUT requests.
Fix:
java
given()
.contentType("application/json") // Add this
.body(requestBody)
.when()
.post("/api/users");16. Running Tests from Command Line
Running tests from the command line is essential for CI/CD integration. Here is how to do it.
Create testng.xml
Create testng.xml in your project root:
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="REST Assured Tutorial Suite" verbose="2">
<test name="API Tests">
<classes>
<class name="com.qatribe.tests.FirstApiTest"/>
</classes>
</test>
</suite>Run All Tests
bash
mvn test
Run Specific Test Class
bash
mvn test -Dtest=FirstApiTest
Run Specific Test Method
bash
mvn test -Dtest=FirstApiTest#test_GetUser_StatusCode200
Run with Environment Variable
bash
mvn test -Denv=staging -DbaseUri=https://staging-api.reqres.in
Skip Tests (Build Only)
bash
mvn clean install -DskipTests
Run with Custom testng.xml
bash
mvn test -DsuiteXmlFile=testng-smoke.xml
17. REST Assured Best Practices for Beginners
Apply these from day one to build good habits that scale.
1. Always Set baseURI Globally
java
// In @BeforeClass or @BeforeSuite
RestAssured.baseURI = "https://reqres.in";
// NOT hardcoded in every test
.get("https://reqres.in/api/users/2") // Bad
.get("/api/users/2") // Good2. Use RequestSpecification for Reusable Setup
java
public class BaseTest {
protected RequestSpecification requestSpec;
@BeforeClass
public void setup() {
requestSpec = new RequestSpecBuilder()
.setBaseUri("https://reqres.in")
.setContentType(ContentType.JSON)
.addHeader("Accept", "application/json")
.build();
}
}
public class UserTest extends BaseTest {
@Test
public void test_GetUser() {
given()
.spec(requestSpec)
.when()
.get("/api/users/2")
.then()
.statusCode(200);
}
}3. Name Tests Clearly
java
// Bad naming
@Test
public void test1() { }
public void apiTest() { }
// Good naming — tells you exactly what is being tested
@Test
public void test_GetUser_WithValidId_Returns200() { }
public void test_CreateUser_WithMissingName_Returns400() { }
public void test_DeleteUser_WithValidId_Returns204() { }Pattern: test_[Action]_[Condition]_[ExpectedResult]
4. Log on Failure Only in CI
java
// For CI/CD environments
given().log().ifValidationFails()
.when().get("/api/users/2")
.then().log().ifValidationFails().statusCode(200);
// For local debugging only
given().log().all()
.when().get("/api/users/2")
.then().log().all().statusCode(200);5. Never Hardcode Test Data
java
// Bad
.body("data.first_name", equalTo("Janet")) // Breaks if data changes
// Good — extract and verify structure, not specific values
.body("data.first_name", notNullValue())
.body("data.id", instanceOf(Integer.class))6. One Assertion Concept Per Test
java
// Bad — testing too many things at once
@Test
public void test_UserApi() {
// 20 assertions in one test
}
// Good — focused tests
@Test
public void test_GetUser_Returns200() { }
@Test
public void test_GetUser_HasCorrectEmail() { }
@Test
public void test_GetUser_ResponseTimeUnder3s() { }7. Use Constants for Endpoints
java
public class ApiEndpoints {
public static final String USERS = "/api/users";
public static final String USER_BY_ID = "/api/users/{id}";
public static final String LOGIN = "/api/login";
public static final String REGISTER = "/api/register";
}
// Use in tests
.get(ApiEndpoints.USER_BY_ID)18. What to Learn Next
You now have a solid foundation in REST Assured. Here is your learning roadmap:
Immediate Next Steps
REST Assured Interview Questions — You have the hands-on knowledge. Now study the questions interviewers actually ask. Our complete REST Assured interview questions guide covers 50+ questions from beginner to architect level with the exact answers you should give.
TestNG Deep Dive — You used @Test and @BeforeClass in this tutorial. TestNG has much more: @DataProvider for data-driven testing, @Factory, parallel execution, listeners, and reporting. Read our TestNG Automation Framework Guide.
Cucumber BDD with REST Assured — Combine REST Assured with Cucumber to write API tests in plain English that business stakeholders can review. Read our Cucumber Automation Framework Guide.
Intermediate Topics to Study Next
- REST Assured Framework Design — Building a scalable, maintainable framework with proper base classes, configuration management, and reporting
- REST Assured Authentication — Deep dive into OAuth 2.0, JWT validation, and API key handling
- JSON Schema Validation — Contract testing between microservices
- Allure Reports — Professional test reporting with screenshots and request/response attachment
Practice APIs for Hands-On Learning
| API | URL | What to practice |
|---|---|---|
| ReqRes | reqres.in | All CRUD operations |
| JSONPlaceholder | jsonplaceholder.typicode.com | GET, POST, PUT, DELETE |
| Petstore | petstore.swagger.io | Complex scenarios, file upload |
| OpenWeatherMap | openweathermap.org/api | API keys, query params |
Final Conclusion
You started this REST Assured tutorial with zero setup and zero test experience. You now have:
- REST Assured fully configured in a Maven project
- Understanding of every HTTP method with real working code
- Knowledge of parameters, headers, authentication, validation, and extraction
- A debugging guide for the most common errors
- Best practices that professional automation engineers use daily
The engineers who get hired are not those who watched tutorials. They are those who wrote the code themselves. Open IntelliJ right now, create the project, and run your first test against reqres.in before you close this page.
That one action separates you from 90% of candidates who read but never practice.
External Resources
- REST Assured Official GitHub
- REST Assured Official Docs
- REST Assured Javadoc
- Maven Central — REST Assured
- Hamcrest Matchers Documentation
- ReqRes — Free Practice API
- JSONPlaceholder — Free Practice API
- TestNG Official Documentation
Published by Ajit Marathe · QaTribe — QA, Automation & Testing Made Simple
🔥 Continue Your Learning Journey
Want to go beyond Rest Assured Interview Questions and crack interviews faster? Check these hand-picked guides:
👉 🚀 Master TestNG Framework (Enterprise Level)
Build scalable automation frameworks with CI/CD, parallel execution, and real-world architecture
➡️ Read: TestNG Automation Framework – Complete Architect Guide
👉 🧠 Learn Cucumber (BDD from Scratch to Advanced)
Understand Gherkin, step definitions, and real-world BDD framework design
➡️ Read: Cucumber Automation Framework – Beginner to Advanced Guide
👉 🔐 API Authentication Made Simple
Master JWT, OAuth, Bearer Tokens with real API testing examples
➡️ Read: Ultimate API Authentication Guide
👉 ⚡ Crack Playwright Interviews (2026 Ready)
Top real interview questions with answers and scenarios
➡️ Read: Playwright Interview Questions Guide