> For the complete documentation index, see [llms.txt](https://osl.mistium.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://osl.mistium.com/tools-and-reference/testing.md).

# Testing

`osl test` discovers files ending in `.test.osl`. With no path, it walks the current directory. Hidden directories, `vendor`, and `node_modules` are skipped.

```bash
osl test
osl test src/
osl test src/users/validation.test.osl
```

Test files are ordinary OSL programs. A thrown error or failed assertion makes the file fail.

## Assertions

```osl
import "std:testing"

testing.equal(add(2, 3), 5)
testing.notEqual(status, "failed")
testing.near(measured, 10, 0.01)
testing.isNull(optional)
testing.notNull(record)
testing.assert(items.len > 0)
testing.panics(def() -> (
  throw "expected"
))
```

Each assertion accepts an optional final message. `testing.fail(message)` fails immediately.

## Direct checks

For small focused tests, direct checks and `throw` are often clearer than an assertion wrapper:

```osl
object parsed = parseInput(source)

if parsed.name != "Ada" (
  throw "parseInput should preserve the name"
)
```

The OriginChats test files use this style for domain behavior. It keeps the failure message next to the rule being tested.

## Discovery and output

The runner sorts discovered paths, compiles each file separately, and prints `PASS` or `FAIL` for each one. It returns status `1` if any file fails.

## Compiler repository checks

The compiler repository's CI runs the full suite with `go test -p 4 ./...` to limit simultaneous package builds. Tests that invoke the OSL CLI report process startup failures and timeouts even when the process produces no output.

When working in the compiler repository, enable Go's race detector for the behavioral suites with `OSL_TEST_RACE=1`:

```bash
OSL_TEST_RACE=1 go test ./tests/language/runtime -run TestUnitThreadSafety -count=1
OSL_TEST_RACE=1 go test ./tests/language/functions -run TestRecords -count=1
```

A race report fails the batch even if individual cases already printed successful results. A timed-out batch preserves completed results and retries unfinished cases individually to identify the timeout.
