JUnit 5 Skill Family
Use this root skill as the package entrypoint for general JUnit 5 requests. Route broad work to the smallest useful subskill. Keep this file light. Read only the subskill and reference files that materially help with the current task.
Responsibilities
- Route broad or ambiguous JUnit 5 requests.
- Apply the shared standards of this package.
- Keep package boundaries clear across authoring, migration, CI, analysis, extensions, architecture, and documentation workflows.
Boundaries
- Do not assume every JVM repo uses Spring, Testcontainers, Mockito, or parallel execution.
- Do not add JUnit 4 APIs in new code unless the task is explicitly about migration.
- Do not silently convert unstable integration tests into mocked unit tests just to make them pass.
- Do not treat JUnit 6 branding as permission to generate non-JUnit-5-compatible patterns for a repo that still targets JUnit 5.
Dispatcher Integration
Use skill-dispatcher as the primary integration layer whenever this package needs help from another skill or when a broader orchestrator is deciding whether JUnit 5 is the right execution layer.
- Prefer dispatcher-led routing by intent rather than naming sibling skills outside this package.
- Prefer the repository's existing JVM test stack over introducing JUnit 5 into a repo that already standardizes on something else.
- Treat sibling skill names in this file as package-local guidance, not as a replacement for global dispatcher routing.
- Keep shared-memory usage limited to stable cross-project policy supplied externally, never task-local routing state.
Routing Map
| Need | Use |
|---|---|
| Generic JUnit 5 request or unclear starting point | core/SKILL.md |
| Writing, fixing, running, or correcting JUnit 5 tests | core/SKILL.md |
| Deriving scenarios from requirements, code, or test case definitions | analysis/SKILL.md |
| Suite structure, fixture ownership, or naming conventions | architecture/SKILL.md |
| Maven, Gradle, Console Launcher, CI, or reporting setup | ci/SKILL.md |
| JUnit 4 to JUnit 5 migration | migration/SKILL.md |
| Custom extensions, callbacks, or parameter resolvers | extensions/SKILL.md |
| Human-readable automation documentation | documentation/tests/SKILL.md |
| Root-cause analysis for failing tests | documentation/root_cause/SKILL.md |
| Non-technical summaries of test outcomes | reporting/stakeholder/SKILL.md |
| IDE-specific local setup help | installers/intellij-junie/SKILL.md or installers/vscode-codex/SKILL.md |
Operating Workflow
- Inspect the repo before prescribing structure. Check build files, Java version, dependencies, test layout, and current JUnit usage.
- Run
scripts/detect-junit-test-context.ps1when repo structure or toolchain is unclear. - Classify the work as component, integration, slice, repository, service-isolated, service-end-to-end, smoke, regression, migration, or extension work.
- Route to the smallest subskill that can complete the task well.
- Run the narrowest relevant test first.
- Preserve traceability to the requirement, code path, or test-case definition when the work begins from source artifacts.
- Keep JUnit 5 compatibility explicit unless the repo has already moved beyond it.
Shared Standards
- Prefer JUnit Jupiter APIs for new test code.
- Prefer deterministic tests over order-dependent or environment-dependent tests.
- Use the lightest test type that still validates the real risk.
- Prefer parameterized tests over copy-pasted examples when inputs vary systematically.
- Prefer soft assertions (
assertAll()) to report multiple failures in one run, ensuring faster correction cycles. - Keep assertions semantic and behavior-focused.
- Use
@Nested, tags, lifecycle control, and extensions deliberately, not as decoration. - Keep heavy framework behavior and infrastructure logic out of plain unit tests.
- Preserve failing evidence before changing assertions or production code.
Read By Need
- Read references/capability-map.md when choosing scope.
- Read references/family-conventions.md before adding new package content.
- Read references/version-compatibility.md when build or dependency versions are unclear.
- Read references/release-checklist.md before publishing or cutting a release.
Gotchas
- Static Lifecycle:
@BeforeAlland@AfterAllmust bestaticby default. Use@TestInstance(Lifecycle.PER_CLASS)only when non-static lifecycle is explicitly required. - Assertion Order: Always use
assertEquals(expected, actual). Swapping them makes failure reports misleading (e.g., "Expected: 5, Actual: 10" when the actual value was 5). - Assertion Masking: Sequential assertions stop at the first failure. Prefer soft assertions (
assertAll()) to execute and report on multiple independent assertions within a single test, allowing many errors to be fixed at once. - Visibility: JUnit 5 test classes and methods should be package-private (no
publicmodifier) unless they must be accessed from other packages. - Import Conflicts: Ensure you import from
org.junit.jupiter.apirather than the oldorg.junit(JUnit 4) package. Mixing them leads to tests that "pass" because they never ran. - Mocking Leakage: When mocking static methods or constructors (e.g., with Mockito), always use a try-with-resources block or an
@AfterEachcleanup to prevent state leakage. - Tag Selection: Using
@Tagwithout corresponding build-tool configuration (Maven/Gradle) means the tests will run even when you think you've excluded them.
Official References
- JUnit overview: https://docs.junit.org/5.14.3/overview.html
- JUnit 5 user guide landing page: https://junit.org/junit5/
Package Shape
core/is the default path for daily JUnit 5 work.analysis/derives executable scenarios from requirements, code, or narrative test definitions.architecture/governs suite shape, ownership, and reuse.ci/covers execution, build tools, and pipeline behavior.migration/handles JUnit 4 to JUnit 5 modernization.extensions/handles reusable callbacks, parameter resolution, and custom annotations.documentation/,reporting/, andinstallers/are optional extensions, not prerequisites for routine test authoring.