Skip to content

Software Testing & QA Tools

REST Assured

REST Assured is a Java library, not a GUI application, for writing automated tests against REST APIs directly inside a test suite. It exposes a fluent given().when().then() domain-specific language that lets a test specify a request and assert on the response's status, headers, and body — including JSON/XML paths via Hamcrest matchers — in a few readable lines instead of hand-rolling HTTP calls and parsing. It's used inside the same JUnit or TestNG test suites a Java team already runs, not as a separate client someone clicks through by hand.

Why it matters

It runs as part of a normal Java test suite, on every build
Because a REST Assured test is just a JUnit or TestNG test method, it runs the same way unit tests do, on every commit in CI, with no separate app or manual step required.
The given/when/then DSL keeps HTTP test code readable
A request with headers, a body, and multiple assertions reads close to plain English instead of the boilerplate of building and parsing a raw HTTP client call by hand.
JSON and XML body assertions don't require a full deserialization step
body("greeting.firstName", equalTo("John")) reaches directly into a response payload with a path expression, without mapping the JSON into a Java class just to check one field.
It fits directly into a Java team's existing tooling
It's a Maven/Gradle dependency like any other test library, so it runs alongside JUnit/TestNG assertions and whatever CI already executes the rest of the test suite, with no separate runner or GUI to install.

The given/when/then DSL

A REST Assured test is built from three parts: given() sets up the request (parameters, headers, an auth scheme, a body); when() specifies the HTTP action and target, like post("/greetXML"); then() asserts on what came back. The style borrows its given/when/then vocabulary from behavior-driven development, and static imports from RestAssured, RestAssuredMatchers, and Hamcrest's Matchers are what let the whole thing read without extra namespacing.

Java
given().
    param("firstName", "John").
    param("lastName", "Doe").
when().
    post("/greetXML").
then().
    body("greeting.firstName", equalTo("John")).
    body("greeting.lastName", equalTo("Doe"));

Where it fits in a Java test suite

REST Assured is added as a Maven or Gradle dependency (io.rest-assured:rest-assured) and called from inside ordinary JUnit or TestNG test methods; there's no separate app, and no exported collection file to keep in sync with code. A test failure shows up the same way any other JUnit failure does, in the same build log, which is what makes it straightforward to fail a CI pipeline on a broken API contract rather than needing a separate reporting step.

Response specifications and reuse

Repeating the same status-code and content-type checks across dozens of tests gets verbose fast, so REST Assured supports building a ResponseSpecification once, via ResponseSpecBuilder, and reusing it across many requests with then().spec(spec). The same pattern exists for requests, via RequestSpecification: a base URL, default headers, and auth can be set up once instead of repeated in every given().

Where REST Assured sits next to Postman and Insomnia

REST Assured has no GUI and nothing to click through; it exists specifically to be code, checked into the same repository as the service or its test suite, and reviewed the same way any other code change is. That's the opposite trade-off from Postman or Insomnia: those tools are faster for manually exploring an unfamiliar API by hand, while REST Assured is what a Java team reaches for once the tests need to live in version control, run in CI on every commit, and integrate with the rest of a Java build rather than being exported and imported as a separate artifact.

Mistakes people make here

Not scoping RestAssured.baseURI between tests
Setting RestAssured.baseURI as a static, global default is convenient for a quick script, but in a larger suite it leaks across tests that expect to hit different hosts — a RequestSpecification scoped to the test class or method avoids one test silently affecting another.
Asserting on a full response body string instead of specific paths
A brittle string-equality check on an entire JSON body breaks the moment field order changes or a new optional field is added; asserting on specific paths with body("field", matcher) only fails when something that actually matters changes.
Writing tests against an API nobody has actually explored by hand first
The DSL is built for asserting on a response whose shape you already understand — writing REST Assured tests against an endpoint nobody has looked at tends to produce tests that encode a guess rather than the real contract. A quick look in Postman, Insomnia, or curl first is often the faster path to a correct test.
Mixing test data setup into the same test method that asserts on the API response
A test that both creates fixture data through side-channel calls and asserts on unrelated behavior gets slow and hard to debug when it fails; separating setup, often in a @BeforeEach or a dedicated fixture, from the actual assertion keeps a failure's cause obvious.
Confusing RestAssuredMockMvc with core REST Assured
Testing a Spring MVC controller in-process, without a running server, uses the separate RestAssuredMockMvc module with its own given/when/then entry points; mixing it up with the core HTTP-based module leads to import and dependency confusion, since the two aren't interchangeable even though the DSL looks nearly identical.

Strengths and trade-offs

Where it is strong

  • Runs inside an existing Java test suite (JUnit/TestNG) and CI pipeline, with no separate app, export step, or GUI involved.
  • The given/when/then DSL keeps request setup and response assertions readable without hand-rolled HTTP client boilerplate.
  • JSON/XML path assertions via Hamcrest reach into a response body directly, without a full deserialization step just to check one field.
  • Reusable request/response specifications cut down on repetition across a large suite of endpoint tests.

The trade-offs

  • It's Java/JVM-specific; a team not already writing Java has to adopt a whole language and build toolchain just to get this library, unlike a standalone GUI client.
  • There's no interactive exploration — understanding an unfamiliar API's actual shape by trial and error is slower here than in a point-and-click client.
  • The DSL's readability depends on team familiarity with its style; a developer unfamiliar with the given/when/then convention or Hamcrest matchers has a real learning curve before tests read as intended.
  • Nothing auto-generates shareable documentation the way a Postman collection can be published — a REST Assured suite documents behavior for other developers reading the test code, not for a non-technical audience.

Who needs this

The natural choice for Java/JVM teams that want their API tests versioned, reviewed, and run in CI alongside the rest of their code, rather than living in a separate GUI tool. Teams working in other languages reach for that ecosystem's equivalent instead (pytest with requests in Python, supertest in Node), and manual or exploratory testing still tends to happen in a GUI client like Postman or Insomnia first.

Questions about rest assured

Is REST Assured a replacement for Postman?
Not really; they solve different parts of the same problem. Postman is best for manually exploring and debugging an API by hand, while REST Assured is for writing automated tests that live in a Java codebase and run in CI. Many teams use both: a GUI client for exploration, REST Assured for the checks that actually gate a build.
Do I need Spring to use REST Assured?
No. The core module tests any REST API over real HTTP regardless of what framework serves it. A separate module, RestAssuredMockMvc, exists specifically for testing a Spring MVC controller in-process without starting a real server, but it's optional and not required to use REST Assured generally.
What testing framework does REST Assured require?
None specifically; it's not a test runner itself. It's typically called from inside JUnit or TestNG test methods, and its own assertions, via then() and Hamcrest matchers, fail the surrounding test the same way a plain assertEquals would.
Can REST Assured test GraphQL or gRPC APIs?
It's built around REST over HTTP, including its own request/response DSL for that; it's not the natural tool for GraphQL or gRPC the way Insomnia or Postman can be used for those protocols directly.

The primary source

Related concepts

← All concept guides