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
| Mode | Configuration | Session and request path |
|---|---|---|
| Remote (default) | pn5.restassured.direct=false | Pumpo 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. |
| Direct | pn5.restassured.direct=true | REST 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.