What Is Rest Assured and Project Setup with Maven

8 min read

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

Rest Assured
  • – 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 to test.
  • Missing the static imports. Without import static io.restassured.RestAssured.* you'll write RestAssured.given() everywhere — works, but the BDD readability collapses. If your IDE auto-completes given(...) as RestAssured.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.0 and json-schema-validator 4.x together. 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.

  1. Confirm java -version reports 17 or higher and mvn -version reports any 3.6+. Install JDK 17 and Maven if either is missing.
  2. In IntelliJ create a new Maven project with GroupId com.mycompany.apitests and ArtifactId api-tests. Confirm pom.xml is at the project root and src/test/java exists.
  3. 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 at src/test/resources/testng.xml. Click "Load Maven changes" in IntelliJ.
  4. Create the package tree: src/test/java/com/mycompany/apitests/{base,models,tests,utils} and src/test/resources/{schemas,testdata}. Drop a minimal testng.xml under resources.
  5. Create tests/HealthTest.java and paste the eight-line example above. Run it from IntelliJ — because https://api.example.com/health doesn'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.
  6. Run mvn dependency:tree from the project root. Find the io.rest-assured:rest-assured line and note what it pulls in transitively (Hamcrest, JsonPath, XmlPath, Apache HttpClient). Knowing what's on your classpath saves debugging time later.
  7. 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.

// tip to track lessons you complete and pick up where you left off across devices.