Skip to main content

test.py

test.py is the build and test helper script for Apache Juneau. It runs the Maven build, the Java tests, a performance guard, the tooling's own Python tests and the browser tests, each as a row on juneau-terminal, which also keeps the logs and the run history. push.py runs it as its test step.

What It Does​

A full run (the default) takes these steps in order, and stops at the first one that fails:

RowWhat it runs
Compilemvn clean install -T1C -DskipTests.
Java testsmvn test -T1C -Drat.skip=true, one block per module.
PerfThe performance guard.
Python testsscripts/tests, the tooling's own pytest suite, through python3 -m pytest when pytest is importable, else uv run --native-tls --with pytest --with pyyaml. With neither, it prints a notice and skips. Nothing is installed.
Browser testsThe *_BrowserTest classes in juneau-console-views, juneau-petstore-core and juneau-terminal-region, under -Pjs-tests. See Browser tests.
TracesThe stack-trace guard over what the rows above printed.

--build-only runs Compile alone. --test-only runs everything after Compile.

Usage​

Full Build and Test (Default)​

python3 scripts/test.py
# or
python3 scripts/test.py --full
# or
python3 scripts/test.py -f

Build Only (Skip Tests)​

python3 scripts/test.py --build-only
# or
python3 scripts/test.py -b

Test Only (No Build)​

python3 scripts/test.py --test-only
# or
python3 scripts/test.py -t

Board Console​

python3 scripts/test.py --console board

Draws one row per step instead of streaming Maven's output, and writes the raw output to a full log whose tail -f command the header prints. See Console view.

Exclude Container-Backed Tests​

python3 scripts/test.py --no-container

Adds -DexcludedGroups=container to the test run, leaving out tests tagged @Tag("container") (the Spring Boot, Jetty and Tomcat container tests), for a faster local loop when you only need core coverage.

Browser Tests​

python3 scripts/test.py --js-tests     # always run them
python3 scripts/test.py --no-js-tests # never run them

The browser tests are excluded from the main test pass and run in their own step, as CI's js-tests, js-tests-petstore and js-tests-terminal jobs do. With neither flag, they run when a .js, .cjs, .css or .ftl file under a src/ tree differs from origin/master (committed, uncommitted or untracked), and otherwise the row shows as skipped. If Node or npm is missing, an automatic run is skipped with a notice, but --js-tests fails. The first run downloads Playwright and Chromium (it needs the network); later runs reuse target/js.

Performance Guard​

After the Java tests pass, the Perf row compares the wall-clock time of mvn test with the suite entry in the project-root perf-baseline.txt, and each module's time from Maven's Reactor Summary with its entry under [modules]. The suite breaches above its baseline plus JUNEAU_CI_PERF_THRESHOLD (default 0.20, so 20%). A module breaches only when it is over that and also more than JUNEAU_CI_PERF_MIN_SECONDS (default 3) seconds over its baseline. A module with no entry is reported and never fails. The report goes to target/perf-guard.txt.

Breaches are warnings unless you pass --enforce-perf:

python3 scripts/test.py --enforce-perf

Stack-Trace Guard​

After the other rows pass, the Traces row scans what they printed for stack traces and fails on any whose header line (for example java.lang.IllegalStateException: boom) is not matched by an entry in scripts/trace-allowlist.txt. Each entry is a regular expression followed by # and the reason it is allowed; an entry with no reason, an invalid expression or a repeated expression fails the row. The report of every trace, allowed or not, goes to target/trace-guard.txt.

The scan reads the run's full log, which exists with --console board or --console none. With the default --console full there is none, so the row is skipped with a warning. --warn-traces reports traces as a warning instead of failing; an allowlist error still fails.

python3 scripts/test.py --console board --warn-traces

Rebaselining​

python3 scripts/test.py --rebaseline

Rewrites the suite line and the [modules] section of perf-baseline.txt from this repository's run history (~/.cache/juneau-terminal/history, see Run history and estimates), prints what changed, and exits without building. Each value is the median of the last --window passing runs (default 20) of the same command shape, rounded up to a tenth of a second, after dropping runs over three times the median. A module whose runs spread by more than 50% takes the 75th percentile instead. Keys with fewer than --min-runs runs (default 5) keep their value, and a module with no history is removed. The rest of the file is kept as it is.

One-Shot JFR Profiling​

python3 scripts/test.py --profile juneau-core/juneau-marshall

Runs mvn test -pl <module> with a Java Flight Recorder recording and writes it to target/profile-results/<module>-<timestamp>.jfr. It replaces the test argLine, so the JaCoCo agent doesn't skew the profile. It runs instead of the build and tests.

Command-Line Options​

OptionEffect
--full, -fClean build, then the tests. The default.
--build-only, -bOnly the build. Can't be combined with --test-only.
--test-only, -tOnly the tests (Java, Perf, Python and Browser), with no build.
--no-containerExcludes @Tag("container") tests.
--js-testsAlso runs the browser tests. Fails if Node or npm is missing.
--no-js-testsNever runs the browser tests. Can't be combined with --js-tests.
--enforce-perfFails the run on a performance-guard breach.
--warn-tracesReports stack traces in the test output as a warning instead of failing the Traces row.
--rebaselineRewrites perf-baseline.txt from the run history, then exits.
--window <n>With --rebaseline: the number of recent runs per key (default 20).
--min-runs <n>With --rebaseline: skips keys with fewer runs than this (default 5).
--console full|board|noneThe console view. Default full, which streams Maven's output live; also JUNEAU_TERMINAL_CONSOLE, and the flag wins.
--detail summary|actionable|modules|allHow many sub-rows a finished row keeps. Default actionable; also JUNEAU_TERMINAL_DETAIL.
--full-log <path>Also appends every byte Maven prints to this file.
--board-log <path>Also appends the board one-line-per-event stream to this file.
--profile <module>Runs a one-shot JFR profile of the module's tests.
--verbose, -vAccepted for compatibility and has no effect: Maven's output always streams live.
--timing-log <path>Ignored, with a warning: timings are in the run history now. It will be removed in a later release.
--help, -hShows the help message.

Environment​

VariableEffect
JUNEAU_MVN_WRAPPERA prefix for every mvn command, such as a lock script that serializes concurrent runs on one checkout.
JUNEAU_CI_PERF_THRESHOLDThe performance guard's tolerance (default 0.20).
JUNEAU_CI_PERF_MIN_SECONDSThe seconds a module must also exceed its baseline by (default 3).
JUNEAU_PUSH_NO_SOUND=1Silences the bell at the end of a run. Under push.py, only push.py rings it.

Exit Codes​

  • 0 - Success.
  • 1 - An unknown option, a conflicting pair of options, or a failed performance guard (with --enforce-perf), Python test run or browser test run.
  • 2 - An invalid --detail value.
  • 130 - Cancelled with Ctrl-C or SIGTERM.
  • Otherwise, Maven's own exit code when the build or Java tests fail.

Requirements​

  • Python 3, and the juneau-terminal sources in the checkout (juneau-terminal/src/main/python/), which the script loads directly.
  • Maven on the PATH.
  • Node and npm for the browser tests, and pytest or uv for the Python tests.

See Also​