Test Runner Contract (Deferred Follow-up)

This document defines the expected behavior for stdlib test running follow-up work.

Scope

Applies to: - stdlib test helpers in stdlib/test.tur - CLI test entry behavior (future tur test command path) - fixture and output conventions for pass/fail reporting

Discovery Model

  1. Directory mode scans tests/fixtures/** for test-bearing fixture directories.
  2. A fixture is considered runnable if it has input.tur.
  3. Error fixtures are identified by tests/fixtures/errors/** and validated against expected.diag.
  4. Non-error fixtures are validated against expected.stdout where provided.

Registration Model

  1. deftest registers test definitions in a global registry in declaration order.
  2. run-tests! executes registered tests in deterministic order (declaration order).
  3. Duplicate test names are rejected with a diagnostic.

Assertion Semantics

Callback Callability Contract (v1)

Process Exit Semantics

Output Contract

Streaming output: - . per passing test - F per failing test

Summary output at end: - total tests - passed - failed - elapsed (optional)

Failure detail block includes: - test name - assertion message / diagnostic snippet - source location if available

Stdout/Stderr Split

Determinism Requirements

Multi-Threaded Fixture Support (T19)

Timeout (expected.timeout)

A fixture directory may contain an expected.timeout file whose content is an integer number of seconds. The test runner kills the compiled binary and marks the fixture as failed if it runs longer than this timeout. The default when the file is absent is 10 seconds. Set the value to 0 to disable the timeout for a fixture.

The runner uses timeout(1) (GNU coreutils), gtimeout (Homebrew coreutils on macOS), or a perl -e 'alarm N' fallback.

ThreadSanitizer (requires.tsan / TUR_TSAN=1)

A fixture directory may contain an empty requires.tsan marker file.

Enable TSan for a full test run:

TUR_TSAN=1 make test
# or using the dedicated target:
make test-tsan

The make test-tsan target rebuilds tur itself with -fsanitize=thread and then sets TUR_TSAN=1 for the test runner.

Follow-up Work Hooks