In the API Testing Masterclass you learned the concepts — HTTP methods, status codes, JSON, authentication. You wrote requests in Postman and curl, asserted on them by hand, and reasoned about what a healthy API contract looks like. This course turns that into committed code: API tests that live in a Maven project, run via TestNG, fail a CI pipeline when the contract breaks, and read like a specification of the system. The library that makes that ergonomic in Java is Rest Assured — and this lesson is the orientation: what it is, why Java teams pick it, and the pom.xml that gets you to your first running test.
What Rest Assured actually is
Rest Assured is a Java library for testing REST APIs. You import a small set of static methods, write a fluent chain that says "given this setup, when I send this request, then assert these things about the response", and the library does the HTTP plumbing for you. Underneath it uses Apache HttpClient (or, optionally, the JDK's built-in HTTP client), Jackson for JSON, Hamcrest for matchers, and JsonPath/XmlPath for extracting fields from response bodies.
What that buys you, in the context of a Java QA team:
- Java-native. Drops into any Maven or Gradle project, runs under TestNG or JUnit 5, integrates with Allure / ExtentReports, and lives in the same repo as the service code if you want it to.
- BDD syntax. The
given().when().then()chain reads like a specification. Code reviewers can scan a test in seconds without parsing imperative HTTP plumbing. - Rich validation. JSONPath ("
users[0].email"), Hamcrest matchers (equalTo,hasItem,containsString), and JSON Schema validation are all first-class — you rarely have to drop down to string parsing. - Two-way serialisation.
body(myUserPojo)serialises a Java object to JSON;extract().as(User.class)deserialises a JSON response back into a typed object. Jackson does the work. - Ubiquitous. It's the most-used Java API testing library on Earth. The community is large, examples on Stack Overflow are plentiful, and "Rest Assured" on a CV is recognised by every recruiter screening Java QA roles.
Rest Assured vs Postman vs requests
Pick the right tool for the team you're on:
- Postman — a GUI tool. Brilliant for manual exploration, debugging an unfamiliar API, and sharing collections with non-developers. Newman runs Postman collections in CI, but Postman scripts are written in JavaScript inside Postman's runner — they live outside your Java source tree.
- Python
requests+ pytest — clean, Pythonic, the right choice if your data engineering team owns the API tests and lives in Python anyway. - Rest Assured — the right choice when your backend is Java/Kotlin, the test suite belongs in the same Maven repo as the service, code review happens in the same place as production code, and CI is built around
mvn test.
These tools are complementary, not exclusive. A common pattern: explore an endpoint in Postman, then commit the canonical test in Rest Assured. The Postman collection is the workshop; the Rest Assured suite is the regression contract.
Maven dependencies — the pom.xml
Rest Assured ships as four artifacts you'll usually want together. Add this to pom.xml under <dependencies>:
<dependencies>
<!-- Rest Assured: the HTTP DSL -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<!-- TestNG: the test runner and assertion library -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.10.2</version>
<scope>test</scope>
</dependency>
<!-- Jackson: serialise POJOs to/from JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
<!-- JSON Schema Validator (used in Chapter 3) -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-schema-validator</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
</dependencies>Two things worth noticing. First, every test-only artifact has <scope>test</scope> — that keeps TestNG and Rest Assured off your production classpath if this same pom.xml ever ships service code. Second, modern Rest Assured pulls in compatible Hamcrest transitively, so you don't normally add org.hamcrest:hamcrest yourself unless you want to pin a specific version.
You also want the Surefire plugin under <build> so mvn test finds and runs your TestNG tests — the Core Java for QA Maven setup lesson covers this in depth and the Selenium with Java chapter on Maven repeats the pattern. The same Surefire config works here unchanged.
Project layout
Maven enforces src/test/java for test code; everything else is convention. The layout this course uses:
api-tests/
├── pom.xml
└── src/test/
├── java/com/mycompany/apitests/
│ ├── base/ ← BaseTest.java (shared @BeforeSuite setup)
│ ├── models/ ← User.java, Product.java POJOs
│ ├── tests/ ← @Test classes
│ └── utils/ ← TokenProvider, data factories
└── resources/
├── testng.xml ← TestNG suite config
├── schemas/ ← JSON Schema files for validation
└── testdata/ ← JSON / CSV / .xlsx fixtures
Same packaging conventions as a Selenium project. If you've completed Core Java for QA, every folder name should already feel familiar.
Static imports — what makes the DSL readable
Rest Assured's signature look — given().when().get(...).then().statusCode(200) — depends on Java's static imports. Add these at the top of every test file:
import static io.restassured.RestAssured.*; // given(), when(), get(), post()...
import static io.restassured.matcher.RestAssuredMatchers.*;
import static org.hamcrest.Matchers.*; // equalTo, hasItem, containsString...Without the static imports you'd write RestAssured.given() and Matchers.equalTo(...) — technically fine but visually noisy. IntelliJ adds these automatically the first time you reference given or equalTo.
A complete first test class — full setup will come in Lesson 3, but this is the shape:
package com.mycompany.apitests.tests;
import org.testng.annotations.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class HealthTest {
@Test
public void healthEndpointReturnsUp() {
given()
.baseUri("https://api.example.com")
.when()
.get("/health")
.then()
.statusCode(200)
.body("status", equalTo("UP"));
}
}Eight lines that read top-to-bottom like a sentence: given the base URI, when I GET /health, then the status code is 200 and the body's status field equals "UP". That readability is what you're paying for.
Where Rest Assured fits
- – Maven / Gradle
- – Java 17
- – TestNG / JUnit 5
- – Apache HttpClient
- – given().when().then()
- – Headers, params, body
- – Hamcrest matchers
- – JsonPath / XmlPath
- – JSON Schema validator
- Jackson (JSON) –
- POJOs ↔ JSON –
- TypeRef for generics –
- Surefire reports –
- Allure / Extent –
- Jenkins / Actions –
The library sits in the middle, but the value comes from how cleanly it composes with the rest of the Java testing stack. You don't have to give up TestNG, you don't have to give up Allure, you don't have to give up Maven Central — Rest Assured speaks all of them natively.
What you should already know
This course assumes Core Java for QA (classes, collections, exception handling, the Maven mindset) and API Testing Masterclass (HTTP verbs, status codes, JSON, auth schemes). We don't re-teach those — but every Rest Assured concept is built up from scratch.
By the end of Chapter 1 you'll have a Maven project running real GET and POST requests and asserting on the response. By the end of the course you'll have a complete API test framework — POJO models, request specs, data-driven tests, JSON Schema validation, and a CI pipeline — for a library management application.
Bookmark the Rest Assured tool entry on qa.codes for the cheat-sheet view of the DSL we're about to spend the rest of the course in.
⚠️ Common mistakes
- Skipping
<scope>test</scope>on test-only dependencies. Without it, Rest Assured and TestNG end up on the production classpath. It compiles fine, but you've shipped a test framework inside a service jar — a smell at minimum and an audit finding at worst. Always scope test libraries totest. - Missing the static imports. Without
import static io.restassured.RestAssured.*you'll writeRestAssured.given()everywhere — works, but the BDD readability collapses. If your IDE auto-completesgiven(...)asRestAssured.given(...), click the lightbulb and "Add on-demand static import." - Adding multiple Rest Assured artifacts at incompatible versions. Don't pin
rest-assured 5.4.0andjson-schema-validator 4.xtogether. The Rest Assured BOM (io.rest-assured:rest-assured-bom) keeps versions aligned for you — or just pick one version and use it for every Rest Assured artifact in the pom.
🎯 Practice task
Get the project skeleton onto disk and confirm the dependencies resolve. 25–35 minutes.
- Confirm
java -versionreports 17 or higher andmvn -versionreports any 3.6+. Install JDK 17 and Maven if either is missing. - In IntelliJ create a new Maven project with GroupId
com.mycompany.apitestsand ArtifactIdapi-tests. Confirmpom.xmlis at the project root andsrc/test/javaexists. - Replace the auto-generated
<dependencies>block with the four entries from this lesson — Rest Assured, TestNG, Jackson, and the JSON Schema validator. Add the Surefire plugin pointing atsrc/test/resources/testng.xml. Click "Load Maven changes" in IntelliJ. - Create the package tree:
src/test/java/com/mycompany/apitests/{base,models,tests,utils}andsrc/test/resources/{schemas,testdata}. Drop a minimaltestng.xmlunder resources. - Create
tests/HealthTest.javaand paste the eight-line example above. Run it from IntelliJ — becausehttps://api.example.com/healthdoesn't actually exist, the test will fail with a connection error. That's expected; the point is that Rest Assured loaded, compiled, and tried to make the call. Read the failure message — it's coming from the library, which is now on your classpath. - Run
mvn dependency:treefrom the project root. Find theio.rest-assured:rest-assuredline and note what it pulls in transitively (Hamcrest, JsonPath, XmlPath, Apache HttpClient). Knowing what's on your classpath saves debugging time later. - Stretch: open the Rest Assured tool entry and skim the DSL surface. You won't recognise most of it yet — that's fine. The point is to see how compact the public API is.
Next lesson: the Given-When-Then chain in detail — what each block is for, how it composes, and the configuration tricks that keep tests DRY across a 200-test suite.