| name | gen-ut |
| description | >- Use when this capability is needed. |
Generate Unit Tests
Input Conventions
Required inputs:
- Target class list (fully-qualified class names are recommended).
Optional inputs:
- Module name (limits Maven command scope).
- Test class list (for targeted execution only; does not limit in-place updates for related test classes).
Default completion level:
- Unless the user explicitly waives or lowers the target, requests such as "add tests" remain bound to
R10-A completion criteria (including default coverage and quality gates).
Missing input handling:
- Note: this section only describes entry handling; final decisions follow
R7/R10.
- Missing target classes: enter
R10-INPUT_BLOCKED.
- Missing test classes: auto-discover with the
TargetClassName + Test convention.
- No related test classes: create
<TargetClassName>Test in the resolved module test source set.
- Cannot resolve
<ResolvedTestModules>: enter R10-INPUT_BLOCKED and request additional module scope.
Terms
<ResolvedTestClass>: one fully-qualified test class or a comma-separated list of test classes.
<ResolvedTestFileSet>: editable file set (space-separated in shell commands), containing only related test files and required test resources.
<ResolvedTestModules>: comma-separated Maven module list used by scoped verification commands.
<ResolvedTargetClasses>: one fully-qualified production class or a comma-separated list of target classes from user input.
Target-class coverage scope: for each target class, aggregate coverage for the target binary class and all binary classes whose names start with <targetBinaryName>$ (including member/anonymous/local classes).
Related test classes: existing TargetClassName + Test classes resolvable within the same module's test scope.
Assertion differences: distinguishable assertions in externally observable results or side effects.
Necessity reason tag: fixed-format tag for retention reasons, using KEEP:<id>:<reason>, recorded in the "Implementation and Optimization" section of the delivery report.
Baseline quality summary: one pre-edit diagnostic run that combines rule scanning, candidate summary, and coverage evidence for the current scope.
Verification snapshot digest: content hash over <ResolvedTestFileSet> used to decide whether a previous green verification result is still reusable.
Gate reuse state: persisted mapping from logical gate names (for example target-test, coverage, rule-scan) to the latest green digest for that gate.
Latest green target-test digest: compatibility alias for the target-test entry in Gate reuse state.
Consolidated hard-gate scan: one script execution that enforces R8, R14, and all file-content-based R15 rules while still reporting results per rule.
Module resolution order:
- If the user explicitly provides modules, use them first.
- Otherwise, resolve by searching upward for the nearest parent
pom.xml from <ResolvedTestFileSet> paths.
- Otherwise, resolve by searching upward for the nearest parent
pom.xml from target class source paths.
Mandatory Constraints
-
Norm levels: MUST (required), SHOULD (preferred), MAY (optional).
-
Definition source principle: mandatory constraints are defined only in this R1-R15 section; other sections only provide term/workflow/command descriptions and must not add, override, or relax R1-R15.
-
R1: MUST comply with AGENTS.md and CODE_OF_CONDUCT.md; rule interpretation should prioritize corresponding clauses and line-number evidence in CODE_OF_CONDUCT.md.
-
R2: test types and naming
- Non-parameterized scenarios
MUST use JUnit @Test.
- Data-driven scenarios
MUST use JUnit @ParameterizedTest(name = "{0}") with @MethodSource + Arguments.
- Parameterized test method signatures
MUST use final String name as the first parameter.
- Parameterized tests
MUST NOT use Consumer (including java.util.function.Consumer and its generic forms) in method signatures or scenario-transport arguments.
- Each parameterized test
MUST provide at least 3 Arguments rows; fewer than 3 is a violation and MUST be converted to non-parameterized @Test.
- Parameterized tests
MUST NOT introduce new nested type declarations (member/local helper class / interface / enum / record) for scenario transport; use Arguments rows plus existing or JDK types instead.
MUST NOT use @RepeatedTest.
- Test method naming
MUST follow CODE_OF_CONDUCT.md: use the assert prefix; when a single test uniquely covers a production method, use assert<MethodName>.
-
R3: change and execution scope
- Edit scope
MUST be limited to .
Workflow
- Read
AGENTS.md and CODE_OF_CONDUCT.md, and record hard constraints for this round (R1).
- Capture scope baseline once:
git status --porcelain > /tmp/gen-ut-status-before.txt.
- Parse target classes, related test classes, and input-blocked state (
R10-INPUT_BLOCKED).
- Resolve
<ResolvedTestClass>, <ResolvedTestFileSet>, <ResolvedTestModules>, and record pom.xml evidence (R3).
- Run a
Baseline quality summary using the bundled baseline script unless equivalent evidence was just produced in the same turn.
- Use the baseline summary to identify current branch-miss lines, existing
R15 risks, and likely R8-CANDIDATES before editing.
SHOULD fix deterministic precheck warnings from the baseline summary before the first standalone target-test run; these warnings are advisory only and do not replace final checkstyle / spotless / hard-gate verification.
- Decide whether
R12 is triggered; if not, output R4 branch mapping.
- For parser / utility classes that return context or value objects,
SHOULD align planned assertions with the returned object's public API before the first target-test run, to avoid internal-branch coverage assertions that do not match externally observable behavior.
- Execute
R8 parameterized optimization analysis, output R8-CANDIDATES, and apply required refactoring.
- Execute
R9 dead-code checks and record evidence.
- Complete test implementation or extension according to
R2-R7.
- Perform necessity trimming and coverage re-verification according to
R13.
- After each edit batch,
SHOULD run one lightweight precheck pass before expensive verification when signatures or parameterized-test structure changed.
- Recommended command:
python3 scripts/scan_quality_rules.py --precheck-only <ResolvedTestFileSet>.
- This pass is advisory and deterministic; it may fail fast on early style issues such as missing
final on test-method parameters, missing @MethodSource, too-few rows, or an invalid first parameter for parameterized tests, but it does not replace formal / / verification.
Verification and Commands
Flag presets:
- Module input provided:
<TestModuleFlags> = -pl <module>
<GateModuleFlags> = -pl <module>
- Module input not provided:
<TestModuleFlags> = -pl <ResolvedTestModules>
<GateModuleFlags> = -pl <ResolvedTestModules>
<FallbackGateModuleFlags> = <GateModuleFlags> -am (for troubleshooting missing cross-module dependencies only; does not change R3 and R10).
- Baseline quality summary (recommended before editing):
python3 scripts/collect_quality_baseline.py --workdir <RepoRoot> \
--coverage-command "./mvnw <GateModuleFlags> -DskipITs -Dsurefire.useManifestOnlyJar=false -Dtest=<ResolvedTestClass> -DfailIfNoTests=true -Dsurefire.failIfNoSpecifiedTests=false -Djacoco.skip=false -Djacoco.append=false -Djacoco.destFile=/tmp/gen-ut-baseline.exec test jacoco:report -Djacoco.dataFile=/tmp/gen-ut-baseline.exec" \
--jacoco-xml-path <JacocoXmlPath> \
--target-classes <ResolvedTargetClasses> \
--baseline-before /tmp/gen-ut-status-before.txt \
<ResolvedTestFileSet>
The baseline script reuses scan_quality_rules.py diagnostics and prints current coverage plus branch-miss lines for each target class.
It also prints deterministic non-blocking precheck warnings for high-frequency style failures such as missing final on test-method parameters or obvious parameterized-test structure issues; these warnings are for early repair only and do not replace formal gates.
0.1 Lightweight precheck pass (recommended after structural edits and before the next standalone target-test):
python3 scripts/scan_quality_rules.py --precheck-only <ResolvedTestFileSet>
This mode is intentionally narrower than the consolidated hard-gate scan. It exists only to catch deterministic early-fix issues cheaply and MUST NOT be used as a replacement for final R14, R15, checkstyle, or spotless verification.
- Target tests:
./mvnw <TestModuleFlags> -DskipITs -Dspotless.skip=true -Dtest=<ResolvedTestClass> -DfailIfNoTests=true -Dsurefire.failIfNoSpecifiedTests=false test
After a green standalone target-test command, record the digest:
python3 scripts/verification_gate_state.py mark-gate-green --state-file /tmp/gen-ut-gate-state.json --gate target-test <ResolvedTestFileSet>
1.1 Verification snapshot digest:
python3 scripts/verification_gate_state.py digest <ResolvedTestFileSet>
1.2 Latest green target-test digest reuse check:
python3 scripts/verification_gate_state.py match-gate-green --state-file /tmp/gen-ut-gate-state.json --gate target-test <ResolvedTestFileSet>
- Coverage:
./mvnw <GateModuleFlags> -DskipITs -Djacoco.skip=false test jacoco:report jacoco:check@jacoco-check -Pcoverage-check
If the module does not define jacoco-check@jacoco-check:
./mvnw <GateModuleFlags> -DskipITs -Djacoco.skip=false test jacoco:report
After a green standalone coverage command, the digest may be recorded for reuse:
python3 scripts/verification_gate_state.py mark-gate-green --state-file /tmp/gen-ut-gate-state.json --gate coverage <ResolvedTestFileSet>
2.1 Target-class coverage hard gate (default target 100 unless explicitly lowered, aggregated over Target-class coverage scope):
bash -lc '
python3 - <JacocoXmlPath> <TargetRatioPercent> <ResolvedTargetClasses> <<'"'"'PY'"'"'
import sys
import xml.etree.ElementTree as ET
xml_path, target = sys.argv[1], float(sys.argv[2])
target_classes = [each.strip() for each in sys.argv[3].split(",") if each.strip()]
if not target_classes:
print("[R10] empty target class list")
sys.exit(1)
all_classes = list(ET.parse(xml_path).getroot().iter("class"))
all_ok = True
for fqcn in target_classes:
class_name = fqcn.replace(".", "/")
matched_nodes = [each for each in all_classes if each.get("name") == class_name or each.get("name", "").startswith(class_name + "$")]
if not matched_nodes:
print(f"[R10] class not found in jacoco.xml: {fqcn}")
all_ok = False
continue
for counter_type in ("CLASS", "LINE", "BRANCH"):
covered = 0
missed = 0
found_counter = False
for each in matched_nodes:
counter = next((c for c in each.findall("counter") if c.get("type") == counter_type), None)
if counter is None:
continue
found_counter = True
covered += int(counter.get("covered"))
missed += int(counter.get("missed"))
if not found_counter:
print(f"[R10] missing {counter_type} counter for {fqcn}")
all_ok = False
continue
total = covered + missed
ratio = 100.0 if total == 0 else covered * 100.0 / total
print(f"[R10] {fqcn} (+inner) {counter_type} covered={covered} missed={missed} ratio={ratio:.2f}%")
if ratio + 1e-9 < target:
print(f"[R10] {fqcn} (+inner) {counter_type} ratio {ratio:.2f}% < target {target:.2f}%")
all_ok = False
if not all_ok:
sys.exit(1)
PY
'
- Checkstyle:
./mvnw <GateModuleFlags> -Pcheck checkstyle:check -DskipTests
- Spotless:
./mvnw <GateModuleFlags> -Pcheck spotless:check -DskipTests
If missing cross-module dependencies occur, rerun the gate command above once with <FallbackGateModuleFlags> and record the trigger reason and result.
4.1 Unified final-gate runner (recommended):
python3 scripts/run_quality_gates.py --workdir <RepoRoot> \
--state-file /tmp/gen-ut-gate-state.json \
--tracked-path <ResolvedTestFileSet> \
--reuse-gate coverage \
--record-gate coverage \
--record-gate hard-gate=rule-scan \
--gate coverage="./mvnw <GateModuleFlags> -DskipITs -Djacoco.skip=false test jacoco:report" \
--gate checkstyle="./mvnw <GateModuleFlags> -Pcheck checkstyle:check -DskipTests" \
--gate spotless="./mvnw <GateModuleFlags> -Pcheck spotless:check -DskipTests" \
--gate hard-gate="python3 scripts/scan_quality_rules.py --baseline-before /tmp/gen-ut-status-before.txt <ResolvedTestFileSet>"
If the environment cannot or should not parallelize, rerun the same command with --serial.
Coverage still remains the authoritative source for target-class counters, and the runner does not relax any gate.
- Consolidated hard-gate scan (
R8, R14, R15-A/B/C/D/E/F/G/H/I/J):
python3 scripts/scan_quality_rules.py --baseline-before /tmp/gen-ut-status-before.txt <ResolvedTestFileSet>
If the user explicitly requested metadata accessor tests in the current turn:
python3 scripts/scan_quality_rules.py --allow-metadata-accessor-tests --baseline-before /tmp/gen-ut-status-before.txt <ResolvedTestFileSet>
The script consolidates repeated file parsing and git-diff inspection without changing rule accuracy. It also evaluates R15-C by comparing the current git status against /tmp/gen-ut-status-before.txt.
For machine-readable automation or quick summaries, the script also supports:
python3 scripts/scan_quality_rules.py --json --baseline-before /tmp/gen-ut-status-before.txt <ResolvedTestFileSet>
python3 scripts/scan_quality_rules.py --summary-only --baseline-before /tmp/gen-ut-status-before.txt <ResolvedTestFileSet>
- Scope validation:
git diff --name-only
Final Output Requirements
MUST include a status line R10=<state>.
MUST include aggregated class-level coverage evidence for each class in <ResolvedTargetClasses> over the Target-class coverage scope (CLASS/LINE/BRANCH counters and ratios).
MUST include R8-CANDIDATES output (candidate set, counts, and per-candidate decision evidence).
MUST include executed commands and exit codes.
- If
R10 is not R10-A, MUST explicitly mark the task as not completed and provide blocking reason plus next action.
MUST NOT use completion wording when R10 is R10-D.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.