Skip to main content

test-order CLI Reference

Practical reference for Maven plugin goals and the most important configuration properties.

Supported Frameworks

test-order supports three test frameworks. The Maven/Gradle plugin auto-detects which is in use.

FrameworkModuleNotes
JUnit 5 / 6test-order-junitFull support: class ordering, method ordering, TDD enforcement, fixed-order orderers, Spring context grouping
Vintage (JUnit 4)test-order-junitVia JUnit Platform Vintage engine; class ordering only (no method orderer API in Vintage)
TestNG 7.x+test-order-testngClass and method ordering via IMethodInterceptor; no TDD enforcement or fixed-order orderers
Kotesttest-order-junitVia JUnit Platform runner (kotest-runner-junit5); class-level ordering; see KOTEST.md

For a detailed side-by-side comparison of JUnit 5 and TestNG integration behaviour, see FRAMEWORK_COMPARISON.md.

Quick Start

# Typical local workflow
mvn test-order:auto test

# If the current project does not declare the plugin and Maven cannot resolve
# the test-order prefix, use the fully-qualified goal instead.
mvn me.bechberger:test-order-maven-plugin:<version>:auto test

# Run deferred tests from the previous auto/select run
mvn test-order:run-remaining test

# Inspect ordering decisions without executing tests
mvn test-order:show

Maven Goals

GoalPurposeTypical use
prepareValidates setup and writes plugin/runtime configurationFirst-time setup, troubleshooting
learnAttach agent for learn mode (pair with test phase)Rebuild dependency index
autoMain developer workflow: select high-value subset and run itFast feedback loop
affectedWrites selected tests to file without executing testsCI orchestration, custom runners
run-remainingExecutes deferred tests from prior selectionFollow-up confidence run
tiered-selectSplits tests into tier 1/2/3 files and runs tier 1Three-phase CI fail-fast workflow
run-tieredRuns all three tiers in a single Maven invocation (tiers 1+2+3)Simpler single-job CI alternative to multi-step tiered flow
run-tierExecutes tier 2 or tier 3 from prior tiered selectionProgressive confidence after tier 1
showUnified view: class order, method order, ML health (auto-detects available data)Debug prioritization
reactor-orderComputes optimal module execution order for multi-module buildsMulti-module CI optimization
dashboardGenerates HTML dashboardVisual analysis
serveServes dashboard via local HTTP serverBrowser compatibility / sharing
optimizeRe-optimizes scoring weights from run historyPeriodic tuning
snapshotSave source/test file hash snapshotsSince-last-run change detection
aggregateAggregates .deps files into the dependency indexAfter distributed/parallel learn runs
dumpPrints dependency index contentsVerify learned dependency mapping
export-jsonExports dependency index as JSONShare/index inspection tooling
diagnoseRuns diagnostic health checks on plugin setup and stateTroubleshooting
compactRebuilds the dependency index from .deps files (removes stale entries)Fix corrupted index / clean up
cleanRemoves all test-order state, indexes, and hash filesStart fresh
downloadDownloads dependency index from CI artifact storeCI warm-start
coverageGenerates least-tested / coverage reportsCoverage gap analysis
detect-dependenciesDetect order-dependent (flaky) tests via reorderingFlaky test detection (see DETECT_DEPENDENCIES.md)
metricsExports test-order metrics as JSONCI/CD reporting, dashboards
helpDisplays all goals and common propertiesQuick reference

Operation Modes (testorder.mode)

Controls what the auto goal does. Pass via -Dtestorder.mode=<value> or set in POM configuration.

ValueBehaviour
auto (default)Learn if no index exists; otherwise select/order.
learnAlways run learn regardless of whether an index already exists.
orderRequire an existing index and run select/order. Warns and exits if no index is found — does not fall back to learn.
optimizeRun the scoring weight optimizer against the stored run history, then save the optimised weights to the state file. Does not run tests.
skipDo nothing. Surefire runs tests in its default order without any test-order influence.

Examples:

# Force a fresh learn pass (re-baseline the index)
mvn test-order:auto test -Dtestorder.mode=learn

# Require index; fail gracefully instead of silently rebaselining
mvn test-order:auto test -Dtestorder.mode=order

# Run weight optimizer and update state file (does not run tests)
mvn test-order:auto -Dtestorder.mode=optimize

# Disable test-order without removing the plugin (e.g., for a hotfix)
mvn test-order:auto test -Dtestorder.mode=skip

Change Detection Modes

Controls which production code changes are used to select and prioritize tests. Pass via -Dtestorder.changeMode=<value> or set in POM configuration.

ModeBest forSummary
autoMost projectsSelects the best available strategy for current environment
since-last-runLocal development without relying on git historyCompares current source snapshots with prior saved hashes
since-last-commitCI/branch validationUses git diff from the previous commit context
uncommittedRapid local iterationUses working-tree/staged changes in current repository
explicitControlled CI pipelinesCaller passes exact class list via testorder.changed.classes

Mode Details and Trade-offs

auto

Automatically selects the best available strategy: since-last-run if a hash snapshot from a previous run exists, otherwise since-last-commit.

Pros: Works out-of-the-box with no configuration; adapts to whether a previous run snapshot is present.
Cons: Non-deterministic across machines; the selected strategy can change if the snapshot is absent. If you need reproducible CI results, prefer an explicit mode.


uncommitted

Detects Java source files with working-tree or staged-but-not-committed changes (git diff + git diff --cached).

Pros: Very fast (single git subprocess); catches changes you haven't committed yet, which is ideal during active development. No hash files needed.
Cons: Requires git. Does not capture changes introduced by earlier commits that are already committed but not yet tested. If a colleague's commit broke something, only the committer would see it.

Use when: Local dev loop where you want to test only what you're actively editing.


since-last-commit

Detects classes changed between the previous commit and HEAD (git diff HEAD~1..HEAD), then merges in any uncommitted changes on top.

Pros: Suitable for CI on pull requests — captures exactly what this PR changed. Works with most CI systems' shallow-clone setups (needs fetch-depth: 2 at minimum).
Cons: Requires git with at least one prior commit (HEAD~1 must exist). The first commit on a new branch may report no changes. Cannot detect changes that span multiple commits without configuring a base ref.

Use when: PR/CI validation where you want to test what changed on the branch.


since-last-run

Compares current file hashes against a snapshot saved during the last learn run. Identifies any source files that changed since that baseline.

Note: Despite the name, the source-hash baseline (hashes.lz4) is only updated during learn mode, not on every run. Multiple consecutive order-mode runs all compare against the same learn-time baseline. Bytecode hashes (bytecode-hashes.lz4) are updated every order run. Use mvn test-order:snapshot to manually advance the source baseline without a full learn run.

Pros: Works without git; portable across VCS-agnostic environments. Captures any file changes regardless of commit history.
Cons: Hash file must exist at testorder.hashFile path (defaults to .test-order/hashes.lz4). First run with no snapshot treats all files as changed. Hash files must be preserved between runs (may need to be committed or cached in CI).

Use when: Non-git environments, or when you want to test "what changed since the last learn run."


explicit

The caller provides the exact set of changed production class FQCNs via testorder.changed.classes.

Pros: Fully deterministic and reproducible — no dependency on git or file timestamps. Easy to integrate with external diff tools, artifact version comparisons, or custom CI scripts. No file I/O needed at detection time.
Cons: Requires the caller to know and supply the changed class list. If the list is wrong or stale, test selection will be wrong. Useful only in scripted/automated pipelines.

Use when: Scripted CI pipelines where you already know the changed classes from a build system, artifact comparison, or external diff tool.

mvn test-order:auto test \
-Dtestorder.changeMode=explicit \
-Dtestorder.changed.classes=com.example.Service,com.example.Repository

Fallback Behavior

If uncommitted or since-last-commit fails (e.g., git not available or no prior commit), test-order automatically falls back to since-last-run if a hash file is present. If no hash file exists, the failure is propagated.

  • Local developer loop: uncommitted
  • Pull request / CI checks: since-last-commit
  • Scripted deterministic pipelines: explicit
  • Mixed environments or simple setup: auto

Core Properties

Property groups at a glance

Jump to the relevant table below — properties are organized by purpose:

General

PropertyDefaultNotes
testorder.skipfalseSkip the plugin entirely for a vanilla test run
testorder.debugfalseEnable debug-level logging
testorder.tddfalseEnforce TDD discipline: new tests that pass without failing first are artificially failed

Files and Paths

PropertyDefault
testorder.index.path (alias: testorder.index)${project.basedir}/.test-order/test-dependencies.lz4
testorder.state.path (alias: testorder.stateFile)${project.basedir}/.test-order/state.lz4
testorder.depsDir${project.build.directory}/test-order-deps
testorder.hashFile${project.basedir}/.test-order/hashes.lz4
testorder.testHashFile${project.basedir}/.test-order/test-hashes.lz4
testorder.methodHashFile${project.basedir}/.test-order/method-hashes.lz4
testorder.bytecodeHashFile${project.basedir}/.test-order/bytecode-hashes.lz4

Selection and Change Detection

PropertyDefaultNotes
testorder.modeautoauto, learn, order, skip — controls auto goal behaviour
testorder.changeModeuncommittedauto, since-last-run, since-last-commit, uncommitted, explicit
testorder.changed.classesunsetRequired in explicit mode; comma-separated FQCNs
testorder.changed.classes.fileunsetPath to file of changed class FQCNs (one per line); merged with testorder.changed.classes
testorder.changed.test.classesunsetComma-separated changed test class FQCNs
testorder.changed.methodsunsetComma-separated changed methods in className#methodName format
testorder.affected.topN-1Top-ranked tests to include (-1 = all affected)
testorder.affected.randomM10Diversity sampling
testorder.affected.seedunsetReproducible random selection
testorder.affected.selectedFile${project.build.directory}/test-order-selected.txtSelected list output
testorder.affected.remainingFile${project.build.directory}/test-order-remaining.txtDeferred list output
testorder.exportJson.outputunsetOutput path for export-json goal (stdout when unset)

Tiered CI

PropertyDefaultNotes
testorder.tiered.tier2Fraction0.5Tier-2 fraction of remaining suite (duration budget if weightByDuration=true)
testorder.tiered.weightByDurationtrueSelect tier 2 by expected duration budget instead of test count
testorder.tiered.tier1File${project.build.directory}/test-order-tier1.txtTier-1 list output
testorder.tiered.tier2File${project.build.directory}/test-order-tier2.txtTier-2 list output
testorder.tiered.tier3File${project.build.directory}/test-order-tier3.txtTier-3 list output
testorder.tiered.currentTierunsetRequired for run-tier (2 or 3)
testorder.tiered.shardunsetSplit tier-3 across N runners: k/N (e.g. 2/3). Tier 1 and 2 run in full on every runner. Works with run-tier, run-tiered, and the Gradle testOrderRunTier/testOrderRunTiered tasks.

Auto Mode

PropertyDefaultNotes
testorder.autoLearnRunThreshold10Force re-learn after N order-mode runs (0 = disabled)
testorder.autoLearnDiffThreshold0Re-learn when changed-class count reaches this (0 = disabled)
testorder.auto.optimizeEvery10Run weight optimization every N auto runs (0 = disabled)
testorder.auto.runRemainingtrue (Maven) / false (Gradle)Print hint to run deferred tests (Maven); auto-run remaining tests via finalizedBy (Gradle)

CI Summary

Writes per-run summaries to target/ (Maven) / build/ (Gradle) after each test selection.

PropertyDefaultNotes
testorder.ci.summaryfalseEnable summary output (test-order-summary.md, .json, test-order-selection-report.xml)
testorder.ci.githubStepSummaryfalseAppend Markdown summary to $GITHUB_STEP_SUMMARY (GitHub Actions only)
testorder.ci.prCommentfalsePost/update a PR comment with the Markdown summary (requires GITHUB_TOKEN env var and GitHub Actions context)

Show (unified)

PropertyDefaultNotes
testorder.show.classestrueInclude class-level order section
testorder.show.methodsfalseInclude method-level order (true/false/auto = show if data exists)
testorder.show.mlfalseInclude ML health analysis (true/false/auto = show if history exists)
testorder.show.allfalseForce all sections on (equivalent to classes+methods+ml)
testorder.showOrder.explainfalseShow per-test scoring breakdown
testorder.showMethodOrder.explainfalseShow per-method scoring breakdown (for show-method-order goal)
testorder.showOrder.fullNamesfalseUse fully qualified class names
testorder.show.formattextOutput format: text or json
testorder.show.filterunsetGlob pattern to restrict output. Matches the full FQCN — use * to match any prefix (e.g. *Service*,*Controller*). Comma-separated patterns use OR semantics. Matching is case-insensitive.
testorder.show.limit20Max tests to display (-1 = all). Stats (score range, counts) always use the full list.
testorder.show.explainfalseShow detailed per-test score breakdown (why each test scored as it did). Equivalent to running test-order:explain.

Reactor Order

PropertyDefaultNotes
testorder.reactor.suggestfalseOutput only the -pl argument (machine-parseable for scripts)
testorder.reactor.topN5Number of top tests to display per module

Reactor Auto-Reordering (Maven lifecycle extension)

The lifecycle extension can reorder Maven reactor modules at build startup so modules with affected tests run first:

PropertyDefaultNotes
testorder.reactorReorderfalseEnable lifecycle-level reactor module reordering by affected test count
testorder.reactorTopNunsetRun only top N modules; set skipTests=true on the rest
testorder.reactorReorder.dryRunfalsePrint planned reorder without modifying the reactor

Show Static Analysis

PropertyDefaultNotes
testorder.showStaticAnalysis.verbosefalseShow full per-class reachability expansion (for show-static-analysis goal)

Dashboard

The dashboard is an interactive HTML report with three tabs: Tests (ranked list, per-test score breakdown, run history), Analytics (APFD timeline, per-run drill-down, rank heatmap, failure correlation, and 15+ analysis panels), and Weights (interactive weight tuning with live rank preview). See test-order-dashboard/README.md for a full feature reference.

PropertyDefaultNotes
testorder.dashboard.output${project.build.directory}/test-order-dashboard/index.htmlOutput path for static dashboard
testorder.dashboard.port0 (auto)Port for serve goal (0 = ephemeral)
testorder.serve.portAlias for testorder.dashboard.port (accepted for convenience)
testorder.dashboard.openfalseOpen browser automatically after dashboard generation
testorder.dashboard.regenerateautoForce dashboard regeneration for serve goal (auto, true, false)
testorder.dashboard.serveSeconds0Stop serve automatically after N seconds (0 = wait until interrupted)

Advanced

PropertyDefaultNotes
testorder.history.maxRuns50Maximum run records to retain in state
testorder.autoCompactEvery50Rebuild index from .deps files every N order-mode runs (0 = disabled)
testorder.structuralDiff.enabledtrueUse structural diff for change complexity scoring
testorder.score.springContextGroupingfalseGroup tests sharing a Spring context
testorder.score.ema.varianceThreshold0.35EMA variance threshold for adaptive smoothing — stored in state file only; setting via -D has no effect
testorder.deps.dropFrequencyThresholdunsetDrop dep classes that appear in more than threshold × total tests entries from the index (valid range: (0, 1)). Useful when a handful of utility classes (e.g. Jackson's ClassUtil) appear in nearly every test and dilute the selection signal. Recommended starting value: 0.8.

Selective Learn

Selective learn mode instruments only the classes reachable from the current source changes (changed classes + their transitive callees up to 4 hops via static call-graph analysis). This keeps per-run overhead proportional to the size of your change rather than the project size.

PropertyDefaultNotes
testorder.learn.selectivefalseEnable selective learn mode — only re-instruments changed classes and transitive callees
testorder.auto.alwaysLearnfalseAlways run a learn pass in auto mode (combine with selective for cheap incremental updates)

When no structural changes are detected the uncertain-class set is empty and instrumentation is skipped automatically — zero overhead on no-change runs.

The Static Analysis tab in the dashboard shows the instrumentation scope from the last selective-learn run (which classes were identified as uncertain, grouped by module). The tab appears automatically when selective-learn data is present.

Instrumentation and Filtering

PropertyDefaultNotes
testorder.instrumentation.modeMEMBERCLASS, METHOD, MEMBER
testorder.instrumentationofflineoffline (build-time) or online (agent at class-load time)
testorder.includePackagesunsetRestricts instrumentation scope
testorder.filterByGroupIdtrueFalls back to project groupId when package detection is empty
testorder.methodOrder.enabledfalseExperimental method ordering
testorder.compressionmedium (Maven) / fast (Gradle)LZ4 compression level for index/state files: fast, medium (HC level 4), or hc (HC level 9, maximum compression)
testorder.source.rootautoOverride main source root directory (replaces automatic detection)
testorder.testSourceRootautoOverride test source root directory (replaces automatic detection)

Static Analysis

PropertyDefaultNotes
testorder.staticAnalysis.enabledtrueEnable static call-graph expansion during change detection
testorder.staticAnalysis.depth2Maximum hops for transitive caller expansion (0–4). Only applies when staticAnalysis.enabled=true

When enabled, changed classes are expanded by static call-graph analysis: callers of changed methods (and their callers) are added to the changed set up to the configured depth. This catches tests that exercise changed code indirectly. Disable (false) to use only direct dependency overlap.

PropertyDefaultNotes
testorder.overrideToolchainunset(Gradle only) Override JDK toolchain selection for test tasks to ensure JDK 17+

ML (Machine Learning) Predictions

PropertyDefaultNotes
testorder.ml.enabledfalseEnable ML history collection during test runs
testorder.ml.predictions.fileautoIntermediate predictions file consumed by test JVM

When enabled, test-order records per-test outcomes (pass/fail, duration, exception type) after each run. With 5+ recorded runs, the ML layer can:

  • Predict failure probability — Tribuo logistic regression trained on 26 features including change coupling, duration trends, co-failure patterns, and failure streaks.
  • Classify test health — Statistical analysis (EWMA, autocorrelation, trend slope) labels tests as HEALTHY, DEGRADING, FLAKY, or FAILING.

ML data is shown in:

  • mvn test-order:show (auto-detected when history exists)
  • mvn test-order:dashboard (ML Health tab + P(fail) column)

Flaky-test Handling and Skip-if-unchanged Cache

All three features below are opt-in and independent of each other. See FLAKY_AND_CACHING.mdx for the full guide.

PropertyDefaultNotes
testorder.flaky.retries0Max retries per FLAKY-classified test method (0 disables). Recommended: 2. Requires JUnit Jupiter auto-detection (junit.jupiter.extensions.autodetection.enabled=true).
testorder.flaky.report.path.test-order/ml-report.txtPath to the ML health report consumed by the runtime extension.
testorder.flaky.quarantinefalseWhen true, persistent FLAKY-test failures are reported as aborted (skipped) rather than failed.
testorder.cache.skipUnchangedfalseSkip tests whose dependencies are unchanged and which have passed the last N runs. The plugin omits them from both selected and remaining lists.
testorder.cache.minPassStreak3Minimum consecutive passing runs before a test becomes cache-eligible.
testorder.cache.maxSkipFraction0.9Safety cap: never skip more than this fraction of the suite. When the cap binds, slower tests are preferred for skipping.

Cache-eligible tests are excluded from the run entirely; retried/quarantined tests are recorded in .test-order/flaky-runtime.txt and surfaced in the CI summary and dashboard.

Scoring Overrides

PropertyDefaultDescription
testorder.score.newTest15Bonus for test classes not in the dependency index
testorder.score.changedTest9Bonus for changed test sources
testorder.score.maxFailure5Cap on failure-based bonus
testorder.score.speed1Bonus for fast tests (full at 1/8× median)
testorder.score.speedPenalty1Penalty for slow tests (full at 8× median)
testorder.score.depOverlap5Max score from dependency overlap (sqrt-normalized)
testorder.score.changeComplexity2Complexity-weighted overlap using compressed diff size
testorder.score.staticFieldBonus0Fixed bonus for tests overlapping a changed static field (requires MEMBER mode)
testorder.score.coverageBonus0Greedy set-cover bonus; when >0 replaces depOverlap+changeComplexity
testorder.score.killRateBonus0Bonus scaled by mutation kill rate; requires analyze-mutations data (0 = disabled)
testorder.score.packageProximityBonus2Bonus when the test class package matches the package of a changed class
testorder.weights.fileunsetPath to TOML weights file; overrides all testorder.score.* properties when set

Method-Level Scoring Overrides

When method-level ordering is active (testorder.methodOrder.enabled=true), these per-component weights tune how individual test methods are ranked within a class. Method scores combine the same change/coverage/speed signals as class scores, but at method granularity using telemetry from MEMBER-mode instrumentation.

Note: These properties apply to JUnit 5/6 (PriorityMethodOrderer) and to TestNG's TestNGPriorityInterceptor when testorder.methodOrder.enabled=true. They have no effect with the Vintage engine, which has no method-ordering API.

PropertyDefaultDescription
testorder.method.score.changedMethod3.0Bonus for methods that touch a changed source method
testorder.method.score.coverageBonus0Greedy set-cover bonus across method telemetry
testorder.method.score.depOverlap2.0Max score from method-level dependency overlap
testorder.method.score.failureRecency3.0Bonus for methods that recently failed
testorder.method.score.fast1Bonus for fast methods (full at 1/8× median runtime)
testorder.method.score.newMethod5.0Bonus for methods absent from the dependency index
testorder.method.score.slow1Penalty for slow methods (full at 8× median runtime)

Build Identification

PropertyDefaultDescription
testorder.build.idunsetOptional opaque identifier stamped onto the run record (e.g. CI build number). Surfaces in the dashboard and JSON exports for traceability.

Verbosity (CLI only)

PropertyDefaultDescription
testorder.verbosefalsePrint full stack traces for non-fatal warnings (e.g. ML training failures). Plugin-side suppression of WARN messages is not currently plumbed — this flag controls extra detail in the standalone CLI only.

Download

PropertyDefaultNotes
testorder.download.fallbackToLearnfalseAutomatically switch to learn mode when the index file cannot be downloaded

Metrics

PropertyDefaultNotes
testorder.metrics.output${project.build.directory}/test-order-metrics.jsonOutput path for the JSON metrics export

Common Recipes

Fast local loop

mvn test-order:auto test \
-Dtestorder.changeMode=uncommitted \
-Dtestorder.affected.topN=5 \
-Dtestorder.affected.randomM=0

PR/CI subset

mvn test-order:auto test \
-Dtestorder.changeMode=since-last-commit \
-Dtestorder.affected.topN=30 \
-Dtestorder.affected.randomM=10

Explicit CI contract

mvn test-order:auto test \
-Dtestorder.changeMode=explicit \
-Dtestorder.changed.classes=com.example.Service,com.example.Repository

ML-powered prioritization

# Enable ML history collection (add to POM or pass on every run)
mvn test -Dtestorder.ml.enabled=true

# After 5+ runs, view ML health analysis
mvn test-order:show -Dtestorder.show.ml=true

# Full report (class order + method order + ML) in JSON
mvn test-order:show -Dtestorder.show.all=true -Dtestorder.show.format=json

# Dashboard includes ML health tab automatically
mvn test-order:dashboard

Dashboard

mvn test-order:dashboard
mvn test-order:serve -Dtestorder.dashboard.port=8080

Useful serve options:

  • -Dtestorder.dashboard.output=... to change output path
  • -Dtestorder.dashboard.port=8080 to set serving port
  • -Dtestorder.dashboard.regenerate=true to force regeneration before serving
  • -Dtestorder.dashboard.serveSeconds=30 to stop automatically after 30 seconds

serve hosts the configured output file over local HTTP, which is useful for:

  • quick local sharing
  • stable refresh URLs
  • browser auto-open workflows

Advanced Workflow Patterns

GitHub Actions example

name: Selective Tests

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'

- name: Fast selective run
run: |
mvn test-order:auto test \
-Dtestorder.changeMode=since-last-commit \
-Dtestorder.affected.topN=20 \
-Dtestorder.affected.randomM=10

- name: Run deferred tests
if: success()
run: mvn test-order:run-remaining test

- name: Alternative tiered workflow (tier 1)
if: false
run: mvn test-order:tiered-select test

- name: Alternative tiered workflow (tier 2)
if: false
run: mvn test-order:run-tier test -Dtestorder.tiered.currentTier=2

- name: Alternative tiered workflow (tier 3)
if: false
run: mvn test-order:run-tier test -Dtestorder.tiered.currentTier=3

Multi-module usage

# Entire reactor
mvn test-order:auto test

# Specific modules
mvn -pl core,api test-order:auto test

TDD Enforcement

When testorder.tdd=true, new test classes and methods that pass without a prior failure in the state file are artificially failed with a descriptive error message. This enforces the red-green-refactor cycle: write the test, see it fail, then make it pass.

# Maven
mvn test -Dtestorder.tdd=true

# Gradle
./gradlew test -Dtestorder.tdd=true

Or set it permanently in the plugin configuration (Maven <tdd>true</tdd>, Gradle tdd = true).

Behaviour:

  • First run (no state file): enforcement is skipped — all tests pass normally.
  • Known test passes: no enforcement — only new classes/methods are checked.
  • New test class passes without prior failure: artificially failed.
  • New test method passes without prior failure: artificially failed (only when method-level data exists in state).
  • Test that already fails: not flagged — TDD discipline is satisfied.

Standalone CLI Tool

The test-order-core module ships a standalone CLI jar:

java -jar test-order-core-jar-with-dependencies.jar <command> [options]

All commands support --help for detailed option descriptions.

Exit codes: All CLI commands return 0 on success and 1 on failure. Failures include: missing index file, invalid arguments (out-of-range threshold, bad mode string), index is empty when content is required (dump, aggregate), missing source root directory (hash-snapshot), and I/O errors. The changed command returns 0 even when no changes are detected — check stdout for "No changes detected." instead.

CommandArgsDescription
aggregate<depsDir> -o <output>Merge .deps files into a dependency index
affected<indexFile> -c <classes>List test classes affected by a set of changed class FQCNs
stats<indexFile>Print dependency index statistics (class count, unique deps, avg deps)
dump<indexFile> [-o file]Dump index as human-readable text (stdout or file)
export-json<indexFile> [-o file]Export dependency index (and optionally state history) as JSON
select<indexFile>Deprecated — use affected instead. Select a prioritized subset: new tests + top-N scored + M diverse fast tests
optimize[stateFile]Analyze run history and optimize scoring weights
hash-snapshot[-s sourceRoot] [-o hashFile]Scan source tree and save file hash snapshot (for since-last-run)
changed[--mode M] [--classes C]Detect changed production classes using the specified mode
run<indexFile> [--mode M]Detect changes and print the affected test classes
struct-diff[files…] [--ref ref]Structural diff of Java files (types, methods, fields) against git
advise<indexFile> [--threshold T]Identify test classes with low method cohesion — candidates for splitting

advise — Test Class Split Analysis

Requires per-method dependency data (collected when testorder.instrumentation.mode=METHOD or MEMBER). Analyzes the pairwise Jaccard similarity of each test method's dependency set within a class. Classes whose methods cover largely disjoint production code are split candidates — breaking them up lets test-order schedule them independently and improves prioritization precision.

java -jar test-order-core.jar advise .test-order/test-dependencies.lz4
java -jar test-order-core.jar advise .test-order/test-dependencies.lz4 --threshold 0.4 --verbose
OptionDefaultDescription
--threshold0.3Similarity threshold in [0,1]; classes below this value are flagged
--verbose / -vfalsePrint per-class details including suggested split groups

struct-diff — Structural Change Analysis

Shows which Java types, methods, and fields have been added, changed, or removed in your source tree — without running a full build.

# Show uncommitted structural changes
java -jar test-order-core.jar struct-diff

# Show changes in the last commit
java -jar test-order-core.jar struct-diff --since-last-commit

# Diff specific files against a git ref
java -jar test-order-core.jar struct-diff src/main/java/com/example/Service.java --ref HEAD~3

Validation Rules (High Impact)

  • testorder.changeMode must be one of the supported modes.
  • testorder.changed.classes is required when changeMode=explicit. If omitted, a warning is printed and the empty set is returned (no tests selected beyond new and @AlwaysRun tests).
  • testorder.affected.topN must be >= -1 (-1 = all affected, positive = exact count, 0 = no top-scored tests but new and @AlwaysRun tests still run — a warning is emitted).
  • testorder.affected.randomM must be >= 0.
  • testorder.instrumentation.mode must be one of: CLASS, METHOD, MEMBER.
  • testorder.coverage.threshold must be >= 1 (minimum number of exercising tests for a class to be "well-tested").

Notes on Property Names

Some runtime keys have canonical and legacy aliases. The following are commonly interchangeable:

  • testorder.index.path and testorder.index
  • testorder.state.path and testorder.stateFile
  • testorder.source.root and testorder.sourceRoot
  • testorder.methodOrder.enabled and testorder.methodOrderingEnabled

Diagnose

When something looks off, diagnose checks index health, agent attachment, framework detection, and configuration issues.