Run
Read a run's results
Every run prints a summary and seals a record under .testkit/results. This page shows how to read both.
On this page
Read the summary
$npx testkit run[1/6] PASS api ui src/web/__testkit__/checkout.ui.testkit.ts 2s
[2/6] PASS api contract src/checkout/__testkit__/refund.contract.testkit.ts 0s
[3/6] PASS api contract src/__testkit__/health.contract.testkit.ts 0s
[4/6] PASS api int src/account/__testkit__/profile.int.testkit.ts 0s
[5/6] PASS api dal src/db/__testkit__/refunds.dal.testkit.ts 0s
[6/6] PASS api int src/checkout/__testkit__/health.int.testkit.ts 0s
Summary
Result: PASSED
Passed: 6
Failed: 0
Skipped: 0
Not run: 0
Files: 6
Duration: 5s
Run ID: 1791891435785-1572397-5c629188A file line gives the file's position, its result, its service, its test type, its path, and how long it took.
| Line | What it counts |
|---|---|
Passed, Failed | Files that ran |
Skipped | Files that a skip rule held back |
Not run | Files that the run selected and did not run |
Files | Every file the run selected |
Runtime errors | Files that failed outside their tests, such as in a setup module. The line appears only when the count is above zero. |
Run ID | The name of the run's directory under .testkit/results/runs/ |
The run prints one line per file and a short block per failure. Service logs and engine output go to disk.
Find a run
$npx testkit artifacts --list1791891435785-1572397-5c629188 passed 2026-10-13T11:37:20.929Z
1791891435201-1572245-010ad857 passed 2026-10-13T11:37:15.203Z
1791891434722-1572097-fbd9051c failed 2026-10-13T11:37:14.724ZThe list is newest first. Every other artifacts command reads the latest run unless you pass --run <id>.
See what a file left behind
Pass a test file to list its artifacts. Each entry has a name, a kind in brackets, a summary, and a path.
$npx testkit artifacts src/checkout/__testkit__/refund.contract.testkit.tstestkit-vitest-report [engine.testkit-vitest-report]
Testkit native Vitest report
.testkit/results/runs/1791891435785-1572397-5c629188/files/artifacts/api/task-4-01-testkit-vitest-report.json
task-engine-native [engine.task.native]
task engine-native evidence
.testkit/results/runs/1791891435785-1572397-5c629188/files/artifacts/api/task-4-01-task-engine-native.json
invocation-engine-native [engine.invocation.native]
invocation engine-native evidence
.testkit/results/runs/1791891435785-1572397-5c629188/files/artifacts/api/task-4-01-invocation-engine-native.jsonThe list does not read the files. To print one, name its kind and ask for text.
$npx testkit artifacts src/checkout/__testkit__/refund.contract.testkit.ts --kind engine.testkit-vitest-report --format text{"schemaVersion":1,"engineId":"node-vitest","invocationId":"1791891435785-1572397-5c629188:lease-4-2:4","taskId":"4","sourceFile":"src/checkout/__testkit__/refund.contract.testkit.ts","result":{"summary":{"numFailedTestSuites":0,"numFailedTests":0,"numPassedTestSuites":1,"numPassedTests":1,"numPendingTestSuites":0,"numPendingTests":0,"numTodoTests":0,"numTotalTestSuites":1,"numTotalTests":1,"success":true},"failures":[],"errors":[]}}The kinds depend on the engine.
| Test | Kinds worth knowing |
|---|---|
| Contract | engine.testkit-vitest-report |
| HTTP and database | engine.summary for the k6 summary, engine.output for k6's stderr |
| Database with fixtures | testkit.dal-fixtures for the seeded records |
| Browser, after a failure | testkit.failure-details and engine.playwright-attachment |
Check that nothing changed
Testkit seals a run when it ends. --verify recomputes every checksum and compares it with the run's manifest.
$npx testkit artifacts --verifyVerified 1791891435785-1572397-5c629188: 186 files (73ad31bf7d5b7b25b930cac190ed1003309dd875c391d0dc966c7e521132d0d4)Where the files are
.testkit/results/
├── latest.json
├── objects/
│ └── sha256/
└── runs/
└── 1791891435785-1572397-5c629188/
├── run.json
├── provenance.json
├── manifest.json
└── files/
├── artifacts/
│ └── api/
└── logs/
└── api-runtime-1__api.log| Path | Holds |
|---|---|
runs/<run-id>/run.json | The run's record: its services, files, results, and timings |
runs/<run-id>/provenance.json | What produced the run: the CI job, the Git commit, and the Testkit and Node versions |
runs/<run-id>/manifest.json | Every file in the run and its SHA-256 checksum |
runs/<run-id>/files/logs/ | Service logs. api-runtime-1__api.log is the output of the api service. |
runs/<run-id>/files/artifacts/<service>/ | Each file's artifacts |
objects/sha256/ | The payloads, stored once per checksum |
latest.json | A copy of the newest run's record. Read it for convenience, and treat runs/ as the record. |
Add .testkit/ to .gitignore.
Read results from a script
--json prints one document for the whole run.
$npx testkit run --json > run.json| Key | Holds |
|---|---|
exitCode | The exit code of the run |
runId | The run's id |
results | One entry per service, with its suites and files |
runArtifact | The run's record. runArtifact.summary.files has passed, failed, skipped, notRun, and total. |
outputMode | The reporter mode |
In Node, @gfdelarue/testkit/workspace exports listRunBundles, loadRunBundleManifest, loadRunBundleArtifact, and verifyRunBundle.
Keep fewer runs
Testkit keeps every run by default. To set a limit, add artifacts.retention.
export default defineConfig({
artifacts: {
retention: {
maxRuns: 50,
maxAgeDays: 30,
},
},
});What leaves your machine
Testkit 0.4.1 has no command that uploads a run's record. The record stays in .testkit/results until you or your CI job copies it somewhere. Gate merges in CI uploads it as a workflow artifact.
Two commands send a summary to GitHub or Gitea. testkit ci report posts a run's result and names each failure by its file and its title. testkit bug file files one bug as an issue.