Skip to main content

REST Assured clients

Pumpo#5 injects RestAssuredApplication into JUnit tests. Call withPumpo() to create a REST Assured RequestSpecification with Pumpo's filters, then use the normal REST Assured request, assertion, and extraction API. Each call to withPumpo() creates a separate specification. Configure authentication, timeouts, object mapping, headers, and other REST Assured options on that specification; Pumpo does not change REST Assured's static defaults.

import dev.pumpo5.remote.restassured.RestAssuredApplication;
import org.junit.jupiter.api.Test;

class AnimalApiTest {
@Test
void readsAnimal(RestAssuredApplication api) {
String name = api.withPumpo()
.header("Accept", "application/json")
.queryParam("include", "name")
.get("https://api.example.test/animals/42")
.then()
.statusCode(200)
.extract().path("name");
}
}

RestAssuredApplication is also an EndpointDsl and a CoreAccessor. You can extend it with a domain-specific interface and default methods, as with other Pumpo clients. The extension resolves both the base interface and interfaces that extend it. For a different request, call withPumpo() again or use a specification according to REST Assured's normal reuse rules. Do not share a reported specification between tests.

REST Assured still handles request bodies, authentication, response assertions, extraction, and object mapping. Expected error statuses can be asserted normally, for example api.withPumpo().get(url).then().statusCode(404). Add a custom REST Assured filter to one specification with api.withPumpo().filter(filter). Pumpo also installs filters from its global store under RestAssuredExtension.REST_ASSURED_FILTERS_KEY and its transport filter. Direct reporting adds a request/response filter when enabled.

Choose the request transport​

ModeConfigurationSession and request path
Remote (default)pn5.restassured.direct=falsePumpo starts a Driver8 session in automatic session mode. Its filter forwards requests through the remote HTTP agent and builds a REST Assured response from the returned status, headers, and body. The driver must be reachable.
Directpn5.restassured.direct=trueREST Assured sends requests from the test process. No Driver8 or WebDriver session is created for this API client. A separate browser client in the same test retains its own session. The test process must be able to reach the API.

For remote mode, configure a reachable webdriver.url and select the Driver8 client with a browserName capability such as pn5-driver8 (as in the parameter example below). The API endpoint URL passed to REST Assured is separate from webdriver.url.

Use src/test/resources/config.conf to select a mode for all REST Assured clients in a test project:

pn5.restassured.direct=true

You can override the setting for one injected parameter. Capability values are resolved when the client is created; type = ValueType.BOOLEAN makes the annotation value a boolean:

import dev.pumpo5.core.webdriver.Capability;
import dev.pumpo5.core.webdriver.ValueType;

@Test
void comparesClients(
@Capability(key = "pn5:restAssuredDirect", value = "true", type = ValueType.BOOLEAN)
RestAssuredApplication directApi,
@Capability(key = "browserName", value = "pn5-driver8")
RestAssuredApplication remoteApi) {
// The second client follows config.conf. Set direct=false and webdriver.url there.
}

The remote mode keeps the usual Pumpo session lifecycle: automatic creation and after-test closure by default, or explicit startSession() and closeSession() when pn5:manualSession is enabled. In direct mode those session methods are no-ops, and Pumpo closes no driver for the API client. Direct mode is suitable for API-only tests without a driver endpoint.

Both modes keep the REST Assured request DSL. Remote mode uses Pumpo's HTTP agent to perform the request, so transport-level REST Assured HTTP client settings apply to direct calls, not to the remote agent. The HTTP DSL is a separate Driver8-based client with its own request builders.

Direct API reporting​

Reporting is an additional opt-in for direct mode only. Enabling reporting while direct mode is off fails at client creation. Set both keys in config.conf:

pn5.restassured.direct=true
pn5.restassured.reporting.enabled=true
pn5.logging.mode.file=true

The file setting writes each test's log to target/reports/<test-class>#<test-method>/pumpo5.log, relative to the test module. Without it, Pumpo writes a file for a failed test only; live and summary logging follow the logging settings.

For each request, the reporting filter writes a matching api-request and api-response entry. Their id contains the test ID, client ID, and a per-client request sequence. Entries contain the HTTP method, a bounded route shape, and either the response status or the transport/error class with elapsed milliseconds. A 4xx or 5xx response is logged as a status and remains available to normal REST Assured assertions. A transport failure is logged by error class and rethrown. Reporting does not retry or consume response bodies.

The built-in reporting entries omit the host, query string, path values, headers, cookies, credentials, tokens, and request and response contents. Route shapes retain only api and version segments such as v1; other segments appear as {segment}. To include only a bounded request body type/size, opt in to pn5.restassured.reporting.payloadShape=true. This never includes body content. Other REST Assured filters and HTTP client debug loggers have their own logging behavior; configure those separately when handling secrets.

The equivalent per-parameter capabilities are pn5:restAssuredReporting and pn5:restAssuredPayloadShape, each with type = ValueType.BOOLEAN. A parameter capability takes precedence over the corresponding config key. Reporting remains off unless explicitly enabled.

Parallel and asynchronous requests​

Create a reported specification during the owning test, or propagate its LogContext to a worker before calling withPumpo(). A specification created without a test log context is rejected. A reported specification used while a different test context is active is also rejected, preventing logs from being written to the wrong test file. Separate injected clients have separate client IDs and request sequences.

import dev.pumpo5.logging.LogContext;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ForkJoinPool;
import static org.junit.jupiter.api.Assertions.assertEquals;

@Test
void checksAsync(RestAssuredApplication api) {
LogContext testLog = LogContext.capture();
int status = CompletableFuture.supplyAsync(
() -> api.withPumpo()
.get("https://api.example.test/health").statusCode(),
testLog.wrap(ForkJoinPool.commonPool())).join();
assertEquals(200, status);
}

You may instead create the specification on the test thread and execute it on a worker; its reporting filter already holds the owning test context. Wrap the worker with LogContext as well if other code there must log to the test. Always await asynchronous work before test teardown, when Pumpo collects the per-test file. See logging in async threads for the context wrappers.