The runner is the component that takes the registered suites and actually executes them. KT Testing Suite Core ships two entry points:Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Octopodo/kt-testing-suite-core/llms.txt
Use this file to discover all available pages before exploring further.
runTests(), a convenience function suitable for the common case, and TestRunner, a class you can instantiate directly when you need finer-grained control over the reporter or filter. Both drive the same execution engine that calls lifecycle hooks, catches test errors, and dispatches events to the reporter at each stage of the run.
runTests()
TestRunner instance and immediately calls run() on it. For most scripts this is the only runner API you need.
The array of root suites to execute. Defaults to the return value of
getSuites(), which contains every suite registered through describe() up to this point in the script. Pass an explicit array when you want to run a subset of suites.The reporter instance that receives lifecycle events. Defaults to a new
ConsoleReporter. Pass a JSONReporter or your own custom reporter to change the output format.An optional case-insensitive substring. When provided, only tests whose full name (all ancestor suite descriptions concatenated with the test name, separated by spaces) contains this substring are executed. Tests that do not match are silently skipped—they are not counted in the totals and do not appear in the reporter output.
Examples
TestRunner class
TestRunner class encapsulates the full execution lifecycle. Instantiate it directly when you need to reuse the same reporter across multiple run() calls, keep a reference for later inspection, or integrate the runner into a larger automation script.
constructor()
The reporter that receives lifecycle events during the run. Defaults to a new
ConsoleReporter instance if omitted.Case-insensitive substring filter applied to the full test name (
"<suite> ... <test>"). Tests whose full name does not contain this string are skipped. Omit or pass undefined to run all tests.run()
onStart before any suite, one onSuiteStart / onSuiteEnd pair per suite (including nested suites), one onTestStart / onTestEnd pair per test, and onFinished with aggregate statistics at the very end.
The root suites to run. Child suites are traversed recursively—there is no need to flatten the tree before calling
run().Internal counters
Two private counters are maintained across the run and included in theonFinished payload:
Incremented each time a test function returns without throwing.
Incremented each time a test function throws any error.
Execution Flow
The diagram below describes the sequence of operations the runner performs for each suite. Nested suites follow the same flow recursively within the parent’s test loop.Test Filtering
The privateshouldSkip() method implements filtering:
fullName is the concatenation of all ancestor suite descriptions plus the test name, separated by spaces. The match is a case-insensitive substring search—no glob or regex syntax is supported.
Error Handling
The runner distinguishes between test errors and hook errors:| Source | Behaviour |
|---|---|
test.fn() throws | Caught; failedTests incremented; onTestEnd called with status: 'failed' and the error object |
beforeEach / afterEach throws | Caught in runHooks; logged to $.writeln as ⚠️ Error in beforeEach: …; run continues |
beforeAll / afterAll throws | Caught in runSuiteHooks; logged to $.writeln as ⚠️ Error in beforeAll: …; run continues |
afterEach hooks always run in a finally block, so they execute even when the test or beforeEach threw.