DOCS·v0.4·Updated weekly

The reference for one test syntax that runs in every language.

Read these docs front to back, or jump in. Each guide is short. The grammar is small. Most teams ship their first cross-runtime test in under an hour.

Specv0.4 · stable
RuntimesPython · JS · Ruby · Perl · Java
LicenseMIT · open source
FormatYAML-style · text
docs/quickstart.tmlPass
# Same file. Every language.
test: "Adds two numbers"
when:
  call: "add(a, b)"
matrix:
  - a: 2, b: 3, expect: 5
  - a: 7, b: 4, expect: 11
then:
  return: expect
INDEX·browse by topic

Find the page that matches the question you opened the tab with.

The docs are split into three short groups. Each entry takes about five minutes to read.

CORE·concepts

Six ideas. The rest of the docs builds on them.

If you know these, you can read any test file in the repo and predict what it does.

01

Test files (.tml)

A test file pairs a setup block with one or more assertion blocks. The syntax stays the same in every runtime.

Read the spec
02

Language bridges

Each bridge maps TestML primitives onto a host runtime. Pick the bridge for your language. The test file never changes.

See bridges
03

Data-driven blocks

Tables of inputs and expected outputs feed the same assertions. One block can drive hundreds of cases.

View examples
04

Assertions

Match by value, regex, JSON shape, or numeric range. Assertions read like documentation and run like code.

Assertion grammar
05

Fixtures & env

Pull values from the host environment with $ENV. Share fixtures across runtimes without rewriting them.

Fixture rules
06

CI integration

Run TestML inside your pipeline. Exit codes, JUnit XML, and a clean diff format slot into existing CI tools.

Pipeline guide
INSTALL·pick any host

One package per language. Zero vendor lock-in.

TestML ships through the package manager your team already uses. Pick the host you build in. The test file stays the same.

There is no paid tier. There is no telemetry. The runtime is open source under the MIT licence.

PythonJavaScriptRubyPerlJava
python · pipOK
$ pip install testml
$ testml run tests/
javascript · npmOK
$ npm install --save-dev testml
$ npx testml run tests/
ruby · gemOK
$ gem install testml
$ testml run spec/
WALKTHROUGH·anatomy of a test

Five blocks. One file. Same shape in every language.

Read the steps left to right. The code on the right matches each step in order.

  1. STEP 01

    Name the case

    The test key holds a short, plain sentence. Reports and CI output use this name as-is. Write it for the next engineer.

  2. STEP 02

    Describe the action

    The when block lists what the host runtime does. Call a function. Hit an endpoint. Read a file. One block per case.

  3. STEP 03

    Feed it data

    The matrix block is a table. Each row becomes a separate run with the same assertions. Edge cases live next to happy paths.

  4. STEP 04

    State the result

    The then block lists assertions. Match a value, a regex, or a JSON shape. Failures point at the row that broke.

  5. STEP 05

    Run it anywhere

    The file does not change. Swap the runtime by swapping the bridge. The Python suite and the Java suite stay in sync by default.

tests/parser_round_trip.tmlPass
# step 01 — name
test: "Parser round-trip preserves keys"

# step 02 — action
when:
  call: "parse_then_dump(input)"

# step 03 — data table
matrix:
  - input: "a: 1"
  - input: "nested:\n  b: 2"

# step 04 — assertion
then:
  equals: input
REFERENCE·cheat sheet

The whole grammar fits on one screen. Keep this tab open.

Bookmark this card. Every key, sigil, and matcher you will see in the wild.

test:Free-text name of the case · string
when:Action to perform before checks · block
then:Expected result after the action · block
matrix:Table of rows that re-run the case · table
$ENV.xRead x from the host environment · ref
/regex/Match a value with a pattern · matcher
@fileInline a fixture stored on disk · loader
#tagMark a case for filtered runs · selector

NEXT·pick a path

Ready to run your first cross-runtime test?

Start with the quickstart for a five-minute green build. Or open the spec and read the grammar end to end. Both paths land in the same place.