Authors REST Assured (Java) API tests using the given().when().then() BDD-style DSL - status code + JSON/XML path assertions + authentication (Basic, OAuth2, API key). Configures Maven / Gradle dependencies, runs via JUnit 5, and emits Surefire / JaCoCo reports for CI gating. Use when the project is on the JVM and wants type-safe API tests in the app's own language; for a Gherkin feature-file flow on the same JVM use karate-testing, for YAML tests on the pytest stack use tavern-testing.
88
90%
Does it follow best practices?
Impact
88%
1.10xAverage score across 10 eval scenarios
Passed
No findings from the security scan
The search team shipped a response change three sprints ago and we found out from a customer. Three things changed at once:
total_count was renamed to totalCount.price_cents (an integer) became price (a string like "42.00").facets started coming back as null instead of an empty array.SearchApiIT was green through all of it, because the assertions only cover
the handful of fields the original author cared about, and none of the three
were among them. Our client code then blew up in production on all three.
The obvious reaction is to write an assertion for every field of every response, and we've started down that road - the file is already the longest in the module and it is only two endpoints. It will not survive being applied to the other eleven, and reviewing a pull request that adds forty one-line assertions is not a real review.
What we actually want is one check per endpoint that says "this is the shape we were built against", living in something a reviewer can read and diff on its own, so that a rename, a type change, or a null where a collection belongs is a red build. The existing behavioural assertions - the ones that check specific values we care about - should stay.
SearchApiIT that fails on
a renamed field, a changed field type, or a null where a collection is
expected.Out of scope: the other eleven endpoints. Do not add new test methods or new HTTP calls.
Extract the following files before beginning.
=============== FILE: src/test/java/com/example/search/SearchApiIT.java =============== package com.example.search;
import io.restassured.RestAssured; import io.restassured.http.ContentType; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.hasSize;
class SearchApiIT {
@BeforeAll static void setup() { RestAssured.baseURI = System.getProperty("api.baseURI", "http://localhost:8080"); }
@Test @DisplayName("a product search returns scored hits") void searchesProducts() { given(). auth().oauth2(System.getenv("API_TOKEN")). accept(ContentType.JSON). queryParam("q", "kettle"). when(). get("/v1/search/products"). then(). statusCode(200). contentType(ContentType.JSON). body("query", equalTo("kettle")). body("hits", hasSize(greaterThan(0))). body("hits[0].sku", equalTo("SKU-1001")); }
@Test @DisplayName("a suggestion lookup returns ranked terms") void suggestsTerms() { given(). auth().oauth2(System.getenv("API_TOKEN")). accept(ContentType.JSON). queryParam("prefix", "ket"). when(). get("/v1/search/suggest"). then(). statusCode(200). contentType(ContentType.JSON). body("suggestions", hasSize(greaterThan(0))). body("suggestions[0].term", equalTo("kettle")); } }
=============== FILE: docs/search-api-responses.md ===============
GET /v1/search/products?q=kettle
{
"query": "kettle",
"total_count": 2,
"facets": [
{ "name": "brand", "count": 2 }
],
"hits": [
{ "sku": "SKU-1001", "score": 0.91, "price_cents": 4200, "in_stock": true },
{ "sku": "SKU-1044", "score": 0.55, "price_cents": 3100, "in_stock": false }
]
}GET /v1/search/suggest?prefix=ket
{
"prefix": "ket",
"suggestions": [
{ "term": "kettle", "weight": 91 },
{ "term": "ketchup", "weight": 12 }
]
}=============== FILE: pom.xml =============== 4.0.0 com.acme search-api-tests 3.1.0-SNAPSHOT
21 UTF-8 io.rest-assured rest-assured 6.0.0 test org.junit.jupiter junit-jupiter 5.10.2 test maven-failsafe-plugin 3.2.5 integration-test verify