elide testA failing test makes the exit code non-zero.
JavaScript and TypeScript
Tests use the node:test API and need no manifest. A file is a test if it matches *.test.*, *.spec.*,
*_test.* or *_spec.*, or is under test, tests or __tests__. Extensions: .js, .mjs, .cjs, .ts,
.mts, .cts.
Discovery skips hidden, dependency and build-output directories, and stops at any nested project (a directory with
elide.pkl, package.json, pom.xml or requirements.txt). A workspace root therefore finds no member tests;
naming a path still runs it.
import test from "node:test";
import assert from "node:assert";
test("adds two values", () => {
assert.equal(1 + 1, 2);
});JVM tests
JVM tests run on the JUnit Platform and need an elide.pkl. src/test is found by convention; a declared set of
type test replaces it (Source Sets).
- Test sets get
testPackagesplus the main set’s dependencies. - Bundled JUnit libraries are added while
jvm.features.testingistrue(the default). processorsrun on test sources.- The test JVM gets
jvm.flagsandjvm.defs(as-D). modulesdependencies of the test and main sets go on--module-pathwith--add-modules=ALL-MODULE-PATH.- Parallel settings in a
junit-platform.propertieson the test classpath override--concurrency.
Select tests
Paths, directories or globs narrow JavaScript and TypeScript discovery:
elide test src/api
elide test src/api/client.test.tsPath arguments skip JVM tests, reporting Path filtering unsupported for JVM tests: <paths>. -t matches test names
in both languages:
elide test -t 'parses .+ headers'JVM tests take JUnit selectors and tag expressions:
elide test --select=class:com.example.ParserTest
elide test --select=method:com.example.ParserTest#parsesHeaders
elide test --select=package:com.example.parser # the package and its subpackages
elide test com.example.parser # a dotted bare token is a package selector
elide test --include-tag=fast --include-tag=unit # fast OR unit
elide test --exclude-tag=slow --exclude-tag=flaky # neither slow nor flaky
elide build test --select=class:com.example.ParserTest
--include-tag='slow & !flaky' is one expression. Tag filters narrow what the selectors chose.
Options
| Option | Effect |
|---|---|
-t REGEX | Match test or enclosing-suite names. |
--select=SELECTOR | JVM: class:, method: or package: selector; repeatable. |
--include-tag=EXPR | JVM: run tests whose tags match; repeats are ORed. |
--exclude-tag=EXPR | JVM: skip tests whose tags match; repeats are ANDed. |
--bail[=N] | Stop after N failures (default 1). |
--test-timeout=MS | Default per-test timeout. |
--timeout DURATION | Time limit for the whole invocation (global). |
--only | Run only tests marked .only. |
--concurrency=N | Run files or JVM classes in parallel. Default 1; 0 is invalid. |
--coverage | Collect coverage; see Coverage. |
--reporter=junit | Write JUnit XML reports. |
--reporter=tap | Write TAP 13 to stdout (and under --reporter-outfile). |
--reporter-outfile=DIR | Report directory. |
--debugger[=MODE|ADDRESS] | Attach a debugger; see below. |
--debugger-host=HOST, --debugger-port=PORT | JavaScript debugger address (DAP: 4711; CDP: 1337). |
--debugger form | Debugs |
|---|---|
| bare | JVM tests over JDWP on 127.0.0.1:5005, and JavaScript tests. |
=5005, =host:5005 | JVM tests only (JDWP). |
=dap, =cdp | JavaScript tests only. |
Grammar: Debugging. An unknown option or missing value fails before anything runs (Build Tasks).
Output and reports
Progress goes to stderr; the final tally goes to stdout:
elide test > summary.txt
elide test 2> progress.txtReporters write to .dev/reports/tests/<language>/<source-set>/. testing.reports in the manifest enables them
without a flag:
import "elide:Testing.pkl" as Testing
testing {
reports { Testing.xmlReport() }
}TAP output
--reporter=tap makes stdout a pure TAP 13 stream:
TAP version 13
# start 1: suite A > t1
# out 1: printed from inside a test
ok 1 - suite A > t1
# start 2: broken
not ok 2 - broken
---
message: "expected 1 to equal 2"
severity: "ERR_ASSERTION"
...
1..2# start <id>marks the start of a test; its output lines are# out <id>: <text>.# out: <text>is not attributed to a test.- Test points are numbered
1..Nin the order tests finish. Join points to tests by the# startline, not the number. - A YAML block appears only on failures with details;
severityis the runner’s error code, when it has one. - Stderr is not framed:
elide test --reporter=tap 2>&1is not valid TAP. - JVM: launcher output is attributed only while exactly one test runs. With
--concurrencyabove 1 or a projectjunit-platform.properties, it is untagged. - JavaScript:
console.loginside a test, and at a file’s top level after importingnode:test, is framed. Output before that import is raw. Hook output is attributed to the test the hook wraps;t.diagnosticis framed as# out.
Coverage
elide test --coverage
elide run --coverageJVM coverage goes to .dev/reports/coverage/jvm/<task>/ as HTML, XML or CSV; JavaScript and TypeScript coverage is
LCOV. The console prints one combined summary.
The top-level coverage block enables collection without the flag:
import "elide:Coverage.pkl" as Coverage
coverage {
enabled = true
scope = "tests"
jvm {
excludes { "org.example.generated.*" }
reports {
Coverage.xmlReport()
Coverage.htmlReport()
}
}
js {
paths { "src" }
}
}| Property | Meaning | Default |
|---|---|---|
enabled | Collect without --coverage. | false |
scope | "tests", "runs" or "all"; --coverage always covers its own task. | "tests" |
jvm.reports | Coverage.htmlReport(), xmlReport(), csvReport(). | none |
jvm.excludes | Class patterns (*, ?) not instrumented, such as generated code. | none |
js.paths | Source roots to report; empty means the whole project. | none |
With coverage, elide run starts a separate JVM process.
Limits
- No Python test discovery.
- JVM tests need a manifest.
- Not implemented:
node:testsnapshots,mock.module, watch mode, programmaticrun(),node:test/reporters.
Supported API: Node test API.