Skip to content

Testing

Run JavaScript and TypeScript node:test files and JUnit tests with elide test: discovery, selecting tests, options, reports and coverage.

On this page

elide test runs JavaScript and TypeScript node:test files and JUnit tests.

elide test

A failing test makes the exit code non-zero.

0:13 / 0:13

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. It stops at any nested project (a directory with elide.pkl, package.json, pom.xml or requirements.txt), so a workspace root finds no member tests. Name a path to run them.

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 the default test source set; a declared source set of type test replaces it (Source Sets).

  • Test sets get testPackages plus the main set’s dependencies.
  • Bundled JUnit libraries are added by default. jvm.features.testing = false removes both the JUnit compile APIs and the bundled runtime; a JVM test run then needs a JUnit console launcher (junit-platform-console) in testPackages, and fails with an error otherwise. Runs that include no JVM tests are unaffected.
  • processors run on test sources.
  • The test JVM gets jvm.flags and jvm.defs (as -D).
  • modules dependencies of the test and main sets go on --module-path with --add-modules=ALL-MODULE-PATH.
  • Parallel settings in a junit-platform.properties on the test classpath override --concurrency.

Select tests

Paths, directories or globs narrow JavaScript and TypeScript tests:

elide test src/api
elide test src/api/client.test.ts

Path arguments skip JVM tests and print Path filtering unsupported for JVM tests: <paths>. -t matches test names in both runners:

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
0:15 / 0:15

--include-tag='slow & !flaky' is one expression. Tag filters apply after selectors.

Output and reports

Progress goes to stderr; the final tally goes to stdout:

elide test > summary.txt
elide test 2> progress.txt

Reporters write to .dev/reports/tests/<language>/<source-set>/. testing.reports in elide.pkl turns them on 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> opens a test; its output lines are # out <id>: <text>. # out: <text> belongs to no test.
  • Test points are numbered 1..N in finishing order. Match points to tests by the # start line, not the number.
  • A YAML block appears only on failures with details; severity is the runner’s error code, if any.
  • Stderr is not framed: elide test --reporter=tap 2>&1 is not valid TAP.
  • JVM: output is tagged with its test only while exactly one test runs. With --concurrency above 1 or a project junit-platform.properties, it is untagged.
  • JavaScript: console.log inside a test, or at top level after importing node:test, is framed. Output before that import is raw. Hook output belongs to the test the hook wraps; t.diagnostic is framed as # out.

Coverage

elide test --coverage
elide run --coverage

JVM coverage goes to .dev/reports/coverage/jvm/<task>/ as HTML, XML or CSV; JavaScript and TypeScript coverage is LCOV, in .dev/reports/coverage/js/lcov.info for tests and .dev/reports/coverage/js/run/lcov.info for runs. The console prints one combined summary. The top-level coverage block collects 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" }
  }
}
PropertyMeaningDefault
enabledCollect without --coverage.false
scope"tests", "runs" or "all"; --coverage always covers its own task."tests"
jvm.reportsCoverage.htmlReport(), xmlReport(), csvReport().none
jvm.excludesClass patterns (*, ?) not instrumented, such as generated code.none
js.pathsSource roots to report; empty means the whole project.none

With coverage, elide run starts a separate JVM process.

Options

OptionEffect
-t REGEXMatch test or enclosing-suite names.
--where CELJavaScript: run tests for which a CEL expression over name, parents and file is true.
--select=SELECTORJVM: class:, method: or package: selector; repeatable.
--include-tag=EXPRJVM: run tests whose tags match; repeats are ORed.
--exclude-tag=EXPRJVM: skip tests whose tags match; repeats are ANDed.
--bail[=N]Stop after N failures (default 1).
--test-timeout=MSDefault per-test timeout.
--timeout DURATIONTime limit for the whole invocation (global).
--onlyRun only tests marked .only.
--concurrency=NRun files or JVM classes in parallel. Default 1; 0 is invalid.
--coverageCollect coverage; see Coverage.
--reporter=junitWrite JUnit XML reports.
--reporter=tapWrite TAP 13 to stdout (and under --reporter-outfile).
--reporter-outfile=DIRReport directory.
--debugger[=MODE|ADDRESS]Attach a debugger; see below.
--debugger-host=HOST, --debugger-port=PORTJavaScript debugger address (DAP: 4711; CDP: 1337).
--debugger formDebugs
bareJVM tests over JDWP on 127.0.0.1:5005, and JavaScript tests.
=5005, =host:5005JVM tests only (JDWP).
=dap, =cdpJavaScript tests only.

Grammar: Debugging. An unknown option or missing value fails before anything runs (Build Tasks).

Limits

  • No Python test discovery; run unittest or pytest instead (Python tests).
  • JVM tests need a manifest.
  • Not implemented: node:test snapshots, mock.module, watch mode, programmatic run(), node:test/reporters.

Supported API: Node test API.

Samples

Start from a template:

elide init --template java        # Java app with a JUnit test
elide init --template ktjvm       # Kotlin app with a test

Was this page helpful?