Outputs & Reports
What each runner emits and how to consume it in CI and locally.
v2 runner (kis test)
Section titled “v2 runner (kis test)”By default no files are written: results stream to the console and the exit code is 0
(all passed) / 1 (any failure). Two opt-in artifacts:
JUnit XML — --junit <path>
Section titled “JUnit XML — --junit <path>”Standard JUnit XML for CI ingestion (GitLab/GitHub test reports, Jenkins):
kis test -t tests/ --junit .test/junit.xmlDuckDB — --db <path>
Section titled “DuckDB — --db <path>”Full structured results for querying and cross-run analysis:
kis test -t tests/ --db .test/results.dbTables:
| Table | Contents |
|---|---|
runs | one row per run: status, run_type, totals (total_tests, passed_tests, failed_tests, skipped_tests, errored_tests), duration_ms |
suite_runs | per-suite rollups, parent-linked (parent_suite_id) |
test_runs | per-test results |
step_runs | per-step results |
assertion_results | per-assertion: expression, passed, field, operator, expected, actual |
http_exchanges | wire evidence per HTTP step: dns_ms, connect_ms, tls_ms, ttfb_ms, transfer_ms, total_ms, request_size, response_size, redirects |
captured_variables | variables extracted during the run |
Query with the DuckDB CLI:
duckdb .test/results.db "SELECT s.step_name, avg(x.total_ms) AS avg_ms, avg(x.ttfb_ms) AS avg_ttfb FROM step_runs s JOIN http_exchanges x ON x.step_run_id = s.id GROUP BY 1 ORDER BY 2 DESC"http_exchanges also stores full request/response headers (JSON) and bodies per step, so a
failing run can be forensically replayed from the DB alone.
Notes:
- DuckDB is single-writer — don’t point two concurrent runs at the same file.
- Load-test metrics tables are planned but not present yet;
--dbcovers functional runs. redirectsis currently always 0.
Console
Section titled “Console”Colored per-test/per-step streaming output; --no-color disables ANSI (auto-disabled when
stdout isn’t a TTY). Diagnostics (env discovery, db/junit paths) go to stderr, results to
stdout.
Tests mode (test.svc tests)
Section titled “Tests mode (test.svc tests)”- Log file:
<prefix>-<RFC3339Nano timestamp>.login the working directory (--prefix, defaulttest), mirrored to stdout.-s/--logresponsesincludes response bodies;-n/--loglinenumbersadds line numbers. - Summary table after the run with canonical columns
TEST PLAN / TEST SCENARIO / TEST CASE / TEST STEP / STATUS / DURATION(✅ pass/❌ fail). Data-driven rows get-RC<n>suffixes when there are ≥ 2 records. - Load mode adds a status line every 100 ms and per-phase summary tables — see Load testing.
- Exit code
1on any failure.
Legacy writers (test.svc load, legacy plan runner)
Section titled “Legacy writers (test.svc load, legacy plan runner)”The v1 pipeline selects writers by type name: log, table, csv, jsonl, std,
distributed. Selection comes from the environment config, not flags:
| Env key | Default | Meaning |
|---|---|---|
<env>.logtype | log | writer for the execution log |
<env>.tabletype | table | writer for the results table (also writes a .csv) |
<env>.output | — | file-name prefix (directory + prefix) |
<env>.logbody | — | include response bodies |
File naming: functional …test-<plan>-<timestamp>.log / .csv; load
…test-load-<timestamp>.log plus <prefix>_summary.txt.
Known quirks:
--output/-oon the legacy commands is accepted but unused — the prefix comes from<env>.output.- In the legacy
test.svc loadpipeline<prefix>_summary.txtis currently created but left empty (the table writer call is disabled); the tests-mode load pipeline does render its phase tables. - The
distributedwriter streams results to the orchestrator instead of local files — see Server modes.