Test Application API
primate/test builds an application in testing mode and exposes its request
pipeline without binding a network listener.
import test from "primate/test";
import type { TestApp } from "primate/test";This entrypoint is part of the primate package. It is distinct from the
repository's separate @primate/test package, which provides framework test
runner and fixture utilities rather than this application-facing harness. See
the Testing guide for complete examples, coverage boundaries,
and dependency-isolation advice.
test()
function test(dirname: string): Promise<TestApp>;Finds the application project root from dirname, creates a unique temporary
build directory beneath that root, builds in "testing" mode, initializes the
serving application without starting its network listener, and resolves to a
TestApp.
Build and initialization failures reject the promise. If setup fails after the temporary output is created, Primate removes that output before rethrowing the original error.
await using app = await test(import.meta.dirname);
const response = await app.request("https://example.test/api/items");
TestApp
Named type export returned by test().
type TestApp = {
request(
url: string | URL,
init?: RequestInit,
): Promise<Response>;
close(): Promise<void>;
[Symbol.asyncDispose](): Promise<void>;
};Each instance has its own built application state and output directory. Application initialization and serve hooks run normally and may have external side effects.
app.request()
request(
url: string | URL,
init?: RequestInit,
): Promise<Response>;Constructs a WHATWG Request with the supplied arguments and sends it through
the initialized application's in-process Request-to-Response pipeline.
The returned native Response exposes the same status, headers, and body
produced by that application path.
The harness exercises application routing, hooks, static assets, request bags and schemas, response conversion, sessions, aborts, and error mapping. It does not exercise HTTP transport, TLS, connection behavior, network backpressure, browser behavior, or WebSocket upgrades. Configured migrations are validated but not automatically applied.
Throws/rejects: Native Request construction errors propagate. Calling
after closure throws Error("Test application is closed"). Application
failures that Primate maps to error responses resolve as those responses rather
than rejecting solely because of their status.
app.close()
close(): Promise<void>;Stops the serving application and removes the instance's temporary build directory. Closure is idempotent: later calls resolve without repeating work. Await it before a test process exits when not using explicit resource management.
app[Symbol.asyncDispose]()
[Symbol.asyncDispose](): Promise<void>;Aliases app.close(), allowing await using to dispose the app
at the end of its scope, including when the scope exits by throwing.
Lifecycle and isolation
Create separate TestApp instances when tests need isolated bundled module
state. Concurrent requests on one instance retain separate request context,
but external services and process-global state used by application hooks are
not automatically isolated. Closing one instance does not close another.