~/testml / examples

Real tests. Five runtimes. One file.

Every example here is a working .tml file. Copy it. Save it next to your code. Run it in Python, JavaScript, Ruby, Perl or Java. The same lines pass on every stack.

FormatYAML-style .tml
Runtimes5 first-class
LicenseMIT, open source
Lock-inNone. Ever.
Filter byHTTPDatabaseCLISnapshotAsync eventsSchema matchFixturesRegex assertions
/examples/recipes

Four recipes you can lift today

Each card is a real .tml file. Each one runs the same on every supported stack. No mocks. No glue code. Just YAML and clear pass results.

tests/api/login.tmlPass
# HTTP login flow — runs in 5 languages
test: "Login returns a session token"
when:
  POST: "/api/login"
  body: { email: "dev@testml.org" }
then:
  status: 200
  json.session: "/^sess_[a-z0-9]{16}$/"

HTTP login flow

Hits a real endpoint. Checks the status code. Matches the session ID against a regex. Works in every supported runtime.

tests/db/orders_fixture.tmlPass
# Database fixture round-trip
fixture: "orders/seed.sql"
test: "Active orders are billed"
when:
  sql: "SELECT count(*) FROM orders WHERE paid"
then:
  rows[0].count: 42
  duration_ms: < 50

Database fixture

Loads a seed file. Runs raw SQL. Checks both the row count and the query time. Catches slow queries before they ship.

tests/cli/build_snapshot.tmlPass
# CLI golden snapshot
test: "build --json prints a stable tree"
when:
  shell: "./bin/build --json"
then:
  exit: 0
  stdout.json: "@snapshot:./golden/build.json"

CLI golden snapshot

Runs a binary. Parses stdout as JSON. Diffs the tree against a saved golden file. Update with one flag when output is meant to change.

tests/events/checkout_emit.tmlPass
# Async event payload shape
test: "checkout emits order.paid"
when:
  call: "app.checkout(cart_id=1)"
then:
  events:
    - type: "order.paid"
      payload.amount: 1999
      payload.cart_id: 1

Async event shape

Calls an action. Catches the emitted events. Pins the type and payload shape so silent regressions never reach prod.

/one-file-many-runtimes

One file. Five runtimes. Zero copies.

Each .tml file is the source of truth. No language port. No mirror suite. Run the same lines from any host. Drop the duplication and the drift.

  • Single test file across Python, JS, Ruby, Perl and Java.
  • Plain YAML shape — no new query language to learn.
  • Native exit codes for clean CI gates.
  • JUnit XML report works in any pipeline.
  • Open MIT licence. Fork it. Ship it.
terminal·5 runtimes
$ python -m testml tests/api/login.tml
Login returns a session token (84ms)
$ node testml.js tests/api/login.tml
Login returns a session token (78ms)
$ ruby testml.rb tests/api/login.tml
Login returns a session token (102ms)
$ perl testml.pl tests/api/login.tml
Login returns a session token (95ms)
$ java -jar testml.jar tests/api/login.tml
Login returns a session token (112ms)

  5/5 runtimes pass · same file · no edits
/install/by-runtime

Pick your stack. Then run the same .tml.

Install once for the runtime you live in. No new SDK. No paid tier. The command below is all you need to start.

pyPython
pip install testml
jsJavaScript
npm i testml
rbRuby
gem install testml
plPerl
cpan TestML
javaJava
mvn add testml
/process/4-steps

From copied snippet to passing CI in four steps

No setup ceremony. No vendor onboarding. Each step takes minutes, not days. Most teams have their first green test the same hour.

  1. STEP 01

    Pick an example

    Open the .tml file. Read the test block. The shape is plain YAML. Nothing else to learn.

  2. STEP 02

    Drop it into your repo

    Save it next to your code. Use any folder name. TestML walks the tree and finds it.

  3. STEP 03

    Run with your runtime

    Call testml from Python, Node, Ruby, Perl or Java. The same file passes in all of them.

  4. STEP 04

    Wire it into CI

    Each runtime exits with a clean code. Pipe the report to JUnit XML. CI dashboards just work.

Start with one example. Ship the rest.

Pick any .tml above. Drop it into your repo. Run it in your stack. The same lines pass on every runtime — no port, no mock, no drift.