Automation Interview
REST Assured Interview Questions and Answers
REST Assured interview questions and answers for Java SDETs: given/when/then syntax, JsonPath, POJO serialization, schema validation, specs, auth, and TestNG.
2,096 words | Article schema | FAQ schema | Breadcrumb schema
Overview
REST Assured is still the default answer when a Java shop asks how you automate APIs, and interviewers know it well enough to catch bluffing. This guide is written for the SDET who lists REST Assured on the resume and now has to defend it in a live technical round. The focus is the code: the given/when/then chain, JsonPath extraction, POJO serialization, schema validation, and how it all snaps into a TestNG framework.
What makes REST Assured interviews distinct from generic API interviews is that they are half about HTTP and half about Java. You will be judged on whether you write clean, DRY, reusable test code, whether you understand serialization, and whether you can explain the difference between a quick script and a maintainable framework. Weak candidates recite the DSL; strong ones talk about specs, POJOs, and reporting.
Every answer below is written to be said out loud in an interview and, where it helps, to be typed on a whiteboard. Keep your code snippets small and correct, name the classes you would use, and always connect a syntax answer back to maintainability. That is the signal senior interviewers are listening for.
Why REST Assured, and the Basics
The opener establishes whether you chose the tool for reasons or just inherited it. Have an opinion.
Q: Why use REST Assured over Postman or a raw HTTP client? Answer: REST Assured lives inside the JVM, so my API tests share the same language, build tool, IDE, and CI as the rest of the Java stack. That means one dependency graph, real code review, POJO reuse with the application models, and native TestNG or JUnit integration. It gives a readable BDD-style DSL for HTTP while keeping the full power of Java for logic, data setup, and assertions. Postman is excellent for exploration and quick collections, but REST Assured is where I put a maintainable regression suite that a whole team owns in version control.
- Q: What are the core static imports? A: RestAssured.given, the Hamcrest matchers (equalTo, hasItem, notNullValue), and often JsonSchemaValidator.matchesJsonSchemaInClasspath.
- Q: What does given() actually set up? A: The request specification: base URI, base path, headers, query and path params, auth, cookies, body, and content type.
- Q: Is REST Assured only for REST? A: It is built for REST/HTTP but can hit any HTTP endpoint, including GraphQL, since a GraphQL call is just a POST with a JSON body.
The given / when / then Structure
This is the question you cannot fumble. Interviewers want to hear the three phases mapped cleanly to arrange, act, assert, with a correct snippet.
Q: Walk me through a given/when/then test and explain each phase. Answer: given() is the setup phase where I configure the request: base URI, headers, auth, and any body. when() fires the actual HTTP call with the verb and path. then() holds the assertions on the response. For example: given().baseUri("https://api.example.com").header("Authorization", "Bearer " + token).when().get("/users/42").then().statusCode(200).body("email", equalTo("a@b.com")). The chain reads like a sentence, which is the point, but I keep it disciplined so it stays readable as tests grow.
- Q: How do you log the request and response? A: log().all() on the request side or .then().log().ifValidationFails() to log only on failure, which keeps CI output clean.
- Q: How do you send a POST with a JSON body? A: given().contentType(ContentType.JSON).body(payloadObject).when().post("/users"), where payloadObject serializes automatically.
- Q: What is the difference between path params and query params here? A: pathParam("id", 42) fills a {id} placeholder in the URL; queryParam("page", 2) adds ?page=2.
Assertions, JsonPath, and Extraction
REST Assured leans on Hamcrest matchers and a Groovy-style JsonPath, and interviewers test whether you can navigate nested JSON and chain calls. This is a favorite area for a live exercise.
Q: How do you assert a nested value and a value inside an array? Answer: I use JsonPath expressions in body(). For a nested field: body("address.city", equalTo("Pune")). For an array element: body("roles[0]", equalTo("admin")). For a collection assertion: body("users.name", hasItem("Asha")). The thing I always mention is that this path syntax is Groovy GPath, not the JSONPath from other tools, so root notation and filters differ slightly, and that trips up people who assume they are identical.
Q: How do you extract a value to reuse in the next request? Answer: I terminate the chain with extract(). For a single value: String id = given()...when().post("/users").then().statusCode(201).extract().path("id"). For the whole response: Response resp = ...extract().response(). Then I pass that id into the next call. Extracting keeps chained scenarios (create then read then delete) honest, because the id flows from the real response instead of being hard-coded.
Serialization and POJOs
This separates scripters from engineers. Building JSON strings by hand is a red flag; using POJOs with Jackson or Gson is the expected answer.
Q: How do you avoid building request bodies as raw strings? Answer: I model the payload as a POJO and let REST Assured serialize it. If I pass a Java object to body() with contentType JSON, REST Assured uses Jackson or Gson (whichever is on the classpath) to serialize it to JSON automatically. On the response side, I deserialize with as(User.class) to get a typed object I can assert on with normal Java. This means my tests reuse the same model classes the app or a shared client uses, refactors are compiler-checked, and I never fight with escaped quotes in a hand-built JSON string.
- Q: What library does REST Assured use for serialization? A: It auto-detects Jackson or Gson on the classpath; Jackson is the common choice, driven by annotations like @JsonProperty and @JsonIgnoreProperties.
- Q: How do you deserialize a response to an object? A: response.as(User.class), or extract().as(User.class) at the end of a then() chain.
- Q: Why prefer POJOs over Maps or strings? A: Type safety, IDE refactoring, reuse of app models, and cleaner assertions than string matching.
JSON Schema Validation
Schema validation is a high-value answer because it shows you protect against contract drift, not just check today's happy path. Name the exact matcher.
Q: How do you validate a response against a JSON schema in REST Assured? Answer: I add the json-schema-validator module and use the matcher: then().body(matchesJsonSchemaInClasspath("user-schema.json")). The schema file lives in src/test/resources so it is on the classpath. This validates structure, types, required fields, and formats in a single assertion, which catches a field silently changing from an integer to a string or a required field disappearing. I still assert specific business values for my scenario, but the schema is the guardrail that fails the build when someone ships a backward-incompatible payload.
Authentication and Reusable Specs
DRY is the theme here. Repeating base URI and auth in every test is the smell interviewers probe for; RequestSpecBuilder and ResponseSpecBuilder are the cure.
Q: How do you handle OAuth2 auth and avoid repeating setup in every test? Answer: For bearer auth I use auth().oauth2(token) or set the Authorization header explicitly. To stay DRY, I build a RequestSpecification once with RequestSpecBuilder, setting base URI, common headers, content type, and auth, then reuse it via given().spec(requestSpec) across the suite. I do the same with ResponseSpecBuilder for common checks like status 200 and JSON content type. When the base URL or a header changes, I edit one builder instead of a hundred tests, and each test file shows only what is unique to that scenario.
- Q: How do you support basic auth? A: given().auth().preemptive().basic(user, pass) so the header is sent on the first request rather than after a challenge.
- Q: Where do tokens and base URLs come from? A: Environment-driven config (system properties, a properties file, or env vars), never hard-coded per environment.
- Q: What is a filter in REST Assured? A: A hook that intercepts every request/response, useful for global logging, adding auth, or capturing data for reports (Allure ships one).
Framework Integration and Data-Driven Tests
For mid and senior roles the interview shifts from syntax to architecture. Show that you know where REST Assured sits in a real, maintained framework.
Q: How do you integrate REST Assured into a TestNG framework with data-driven tests and reporting? Answer: TestNG @Test methods hold the scenarios, and @DataProvider feeds multiple payloads so one test method covers many positive and negative rows. Request and response models are POJOs serialized with Jackson. Common setup lives in specs built in a base class or a factory. I add Allure or Extent for reporting and attach the request and response on failure through a filter, so a red test in CI shows exactly what was sent and returned. Base URI and secrets are config-driven per environment, and tests create and clean their own data so they run in parallel without collisions.
- Q: How do you run the same test across environments? A: Externalize base URI and secrets into config selected by a system property like -Denv=staging.
- Q: How do you enable parallel execution? A: TestNG parallel settings plus fully independent tests: no shared mutable data, each test creates and tears down its own records.
- Q: How do you report on API failures usefully? A: Log or attach the full request and response on failure only, so passing runs stay quiet and failures are self-explanatory.
Common Gotchas and Coding Questions
Expect a couple of trick questions that reveal depth. These are the details that only someone who has debugged a real suite would know.
Q: A REST Assured test passes locally but fails in CI with an SSL or connection error. What are the likely causes? Answer: Common ones are a self-signed certificate in a lower environment (fixed with relaxedHTTPSValidation for that env only, never in production tests), a proxy required in CI but not locally, a different base URL resolved by environment config, or timing where the service is not yet ready when the pipeline runs. I confirm by logging the resolved base URI and the full request in CI, then reproduce with the CI config locally rather than guessing.
Q: How do you assert response time? Answer: then().time(lessThan(800L)) checks the round trip is under a threshold. I treat it as a soft signal in functional tests, not a substitute for a real load test, and I keep the threshold generous to avoid flakiness from CI noise.
Frequently Asked Questions
What is the given when then syntax in REST Assured?
It is a BDD-style chain where given() configures the request (base URI, headers, auth, body), when() sends the HTTP verb and path, and then() holds the assertions on the response. It maps directly to the arrange, act, assert pattern and reads like a sentence.
How do you validate a JSON schema in REST Assured?
Add the json-schema-validator module and assert with then().body(matchesJsonSchemaInClasspath("schema.json")), keeping the schema file in src/test/resources. It validates structure, types, required fields, and formats in one assertion and catches backward-incompatible changes.
How do you extract a value from a response in REST Assured?
End the chain with extract(). Use extract().path("id") for a single value or extract().response() for the whole response, then pass that value into the next request. This keeps chained flows like create-read-delete honest and data-driven.
Why use POJOs instead of JSON strings in REST Assured?
POJOs give type safety, IDE refactoring, and reuse of the application's model classes. REST Assured serializes them with Jackson or Gson automatically, so you avoid escaped-quote bugs in hand-built strings and get cleaner assertions when deserializing responses.
How do you avoid repeating base URI and auth in every REST Assured test?
Build a RequestSpecification once with RequestSpecBuilder (base URI, headers, auth, content type) and reuse it via given().spec(spec). Use ResponseSpecBuilder for common response checks. When config changes you edit one builder instead of every test.
How do you run REST Assured tests in CI with data-driven inputs?
Drive scenarios with TestNG @Test and @DataProvider for multiple rows, select the environment with a system property, and make each test create and clean its own data so runs are parallel-safe. Add Allure or Extent and attach request and response on failure.
Is REST Assured still relevant in 2026?
Yes, in Java-heavy organizations it remains the standard for maintainable API regression suites because it shares the language, build, and CI with the application. Teams on other stacks may prefer Playwright or a native library, but the REST Assured concepts transfer directly.