Integrations
Use familiar test tooling and product boundaries to exercise the software that users rely on.
Familiar tools, connected evidence
Testkit is designed to complement tools developers and coding agents already use. Depending on the boundary being tested, familiar tools can include browser automation, unit test runners, source history, containers, and data services.
Playwright
Use the playwright engine for UI suites. Testkit manages the Playwright runtime — no separate npx playwright install step is required in CI. The suite file suffix must be .ui.testkit.ts.
// src/checkout/__testkit__/checkout.ui.testkit.ts
import { defineFile } from "@(scope)/testkit";
import { test, expect } from "@(scope)/testkit/playwright";
export const testkit = defineFile({ engine: "playwright" });
test("checkout completes after a network interruption", async ({ page }) => {
await page.goto("/checkout");
// simulate a dropped connection on the first payment attempt
await page.route("**/api/payment", route => route.abort());
await page.getByRole("button", { name: "Pay" }).click();
await expect(page.getByText("Something went wrong. Try again.")).toBeVisible();
});Vitest
Use the node-vitest engine for data and contract suites. Testkit invokes Vitest through its own managed runtime, so a top-level vitest.config.ts is not required. The suite file suffix must be .data.testkit.ts or .contract.testkit.ts.
// src/billing/__testkit__/invoice.data.testkit.ts
import { defineFile } from "@(scope)/testkit";
import { describe, it, expect } from "@(scope)/testkit/node-vitest/data";
export const testkit = defineFile({ engine: "node-vitest" });
describe("invoice line totals", () => {
it("multiplies quantity by unit price", () => {
expect(lineTotal({ quantity: 3, unitPrice: 1000 })).toBe(3000);
});
it("returns zero for an empty line", () => {
expect(lineTotal({ quantity: 0, unitPrice: 500 })).toBe(0);
});
});Git
No additional configuration is needed. Testkit reads Git metadata at run time to attach the current commit SHA, branch, and dirty-state flag to each sealed run bundle. The result is visible in .testkit/results/runs/<run-id>/run.json under the provenance key.
Docker and PostgreSQL
Declare a managed Postgres service in testkit.config.ts and Testkit provisions an isolated Docker-managed database for the run. The connection string is injected into the suite environment automatically.
// testkit.config.ts
import { app, database, defineConfig } from "@(scope)/testkit/config";
export default defineConfig({
services: {
api: app.node({ cwd: ".", entry: "src/index.ts", port: 3004 }),
db: database.postgres({ runtimeConnections: 20 }),
},
});Use npx testkit destroy to release the Docker-managed database when it is no longer needed. See Operations for cleanup guidance.