Docs

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.

View as Markdown

On this page
  1. Read the summary
  2. Find a run
  3. See what a file left behind
  4. Check that nothing changed
  5. Where the files are
  6. Read results from a script
  7. Keep fewer runs
  8. What leaves your machine

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-5c629188

A file line gives the file's position, its result, its service, its test type, its path, and how long it took.

LineWhat it counts
Passed, FailedFiles that ran
SkippedFiles that a skip rule held back
Not runFiles that the run selected and did not run
FilesEvery file the run selected
Runtime errorsFiles that failed outside their tests, such as in a setup module. The line appears only when the count is above zero.
Run IDThe 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 --list
1791891435785-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.724Z

The 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.ts
testkit-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.json

The 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.

TestKinds worth knowing
Contractengine.testkit-vitest-report
HTTP and databaseengine.summary for the k6 summary, engine.output for k6's stderr
Database with fixturestestkit.dal-fixtures for the seeded records
Browser, after a failuretestkit.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 --verify
Verified 1791891435785-1572397-5c629188: 186 files (73ad31bf7d5b7b25b930cac190ed1003309dd875c391d0dc966c7e521132d0d4)

Where the files are

.testkit/results/
.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
PathHolds
runs/<run-id>/run.jsonThe run's record: its services, files, results, and timings
runs/<run-id>/provenance.jsonWhat produced the run: the CI job, the Git commit, and the Testkit and Node versions
runs/<run-id>/manifest.jsonEvery 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.jsonA 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
KeyHolds
exitCodeThe exit code of the run
runIdThe run's id
resultsOne entry per service, with its suites and files
runArtifactThe run's record. runArtifact.summary.files has passed, failed, skipped, notRun, and total.
outputModeThe 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.

testkit.config.ts
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.

  1. OverviewStartWhat Testkit is, and what you need to run it.
  2. Get startedStartFive steps from install to a merge gate.
  3. Test filesWrite testsWhere a test lives and what its name means.
  4. Contract testsWrite testsCall your running service from Node.
  5. HTTP testsWrite testsDrive routes with k6, signed in as named actors.
  6. Browser testsWrite testsAssert on a real page in Chromium.
  7. Database testsWrite testsRun SQL against a Postgres that Testkit builds.
  8. CIRunOne command decides whether a pull request merges.
  9. ResultsRunWhere a run's evidence lands and how to read it.
  10. CLIRunEvery command and flag.
  11. ConfigurationRunEvery field of testkit.config.ts.
  12. CampaignsHunt bugsGive your agent a target and collect proven bugs.
  13. Bug reportsHunt bugsThe five things every issue states.
  14. TurnstoneTurnstoneWhat the dashboard keeps, and what it never stores.
  15. Connect GitHubTurnstoneConnect a repository, and see the access Turnstone asks for.
  16. Connect GiteaTurnstoneAdd your Gitea host, then connect a repository.
  17. SyncTurnstoneWhen Turnstone reads your issues, and what it reads.
  18. FactsTurnstoneEach fact about a bug, and where Turnstone reads it.