Add reusable ArchUnit rule and example project for coverage annotations#14
Merged
Conversation
…amples
Both <pre> blocks in ExcludeFromJacocoGeneratedCodeCoverage.java used
the invalid positional (single-argument) annotation syntax:
@ExcludeFromJacocoGeneratedCodeCoverage("Spring Boot entry point")
The annotation declares only a named element (justification), so the
positional shorthand is not legal and would cause a compile error if
copied verbatim by a consumer.
Both occurrences are replaced with the correct named syntax:
@ExcludeFromJacocoGeneratedCodeCoverage(justification = "Spring Boot entry point – not unit-testable")
No behaviour change — Javadoc only.
…xtures artifact Motivation ---------- Consumers of sedr-library need a ready-made ArchUnit rule that enforces the convention that every @ExcludeFromJacocoGeneratedCodeCoverage annotation must carry a non-blank justification. Shipping this rule as a test-fixtures artifact means every project can reuse it with a single dependency declaration instead of copy-pasting the check. What changed ------------ sedr-library/build.gradle - Apply the built-in 'java-test-fixtures' Gradle plugin so the testFixtures source set is compiled and published alongside the main jar. - Remove the unused 'import groovy.json.JsonSlurper' (caused a VS Code compile error; the import was pre-existing but latent). - Refactor resolveVersion to use gh's built-in --jq filter instead of JsonSlurper for JSON parsing, eliminating the Groovy dependency. - Add a dependencies block declaring testFixturesApi for archunit-junit5 and junit-jupiter-api so they are transitive to consumers of the fixture. sedr-library/gradle/libs.versions.toml - Add archunit = "1.4.2" and junit-jupiter = "5.14.4" to [versions]. - Add archunit-junit5 and junit-jupiter-api entries to [libraries]. - Includes refreshVersions comment-style candidates for both artifacts. sedr-library/src/testFixtures/java/.../AbstractCoverageExclusionConventionsTest.java - New public abstract class in the same package as the annotation. - Declares protected abstract String getBasePackage() for subclasses to scope the scan to their own root package. - Single @test coverageExclusionAnnotationsMustHaveJustification() uses ClassFileImporter (DO_NOT_INCLUDE_TESTS) + a custom ArchCondition that separately checks class-level, constructor-level, and method-level usages of @ExcludeFromJacocoGeneratedCodeCoverage for a non-blank justification value. - Javadoc shows the extend-and-override pattern and the Gradle dependency snippet. How consumers use it -------------------- 1. Add to build: testImplementation(testFixtures("com.arc-e-tect.sedr.utils:sedr-library:VERSION")) 2. Write a one-method subclass overriding getBasePackage(). 3. The inherited test runs automatically in the JUnit Platform. Side effects / caveats ----------------------- - Gradle emits POM metadata warnings about testFixtures capability mapping. This is cosmetic and only affects Maven consumers on Gradle < 6; Gradle 6+ module metadata handles it correctly. - 'from components.java' in the existing MavenPublication block automatically includes the testFixtures variant — no changes to the publishing block needed.
Motivation
----------
A runnable example makes it concrete how consumers integrate both the
@ExcludeFromJacocoGeneratedCodeCoverage annotation and the reusable
AbstractCoverageExclusionConventionsTest, and demonstrates that the ArchUnit
rule correctly distinguishes compliant from non-compliant usage.
Location
--------
examples/sedr-library/jacoco-marker/
What's included
---------------
Build infrastructure
- settings.gradle — standalone Gradle project named 'jacoco-marker-example'.
- build.gradle — applies java plugin; declares mavenLocal() first then
mavenCentral() so locally published snapshots resolve
during development without any change post-release;
declares implementation and testImplementation(testFixtures)
against sedr-library 0.2.6; adds junit-jupiter-engine and
junit-platform-launcher as testRuntimeOnly.
- gradle/wrapper/ — Gradle wrapper copied from sedr-library so the example
is self-contained.
Production sources
- CompliantService.java — method annotated with @ExcludeFromJacocoGeneratedCodeCoverage
with a non-blank justification; the ArchUnit rule passes.
- NonCompliantService.java — method annotated with @ExcludeFromJacocoGeneratedCodeCoverage
without a justification; the ArchUnit rule raises a violation.
Test sources
- CoverageExclusionConventionsTest.java — extends AbstractCoverageExclusionConventionsTest;
overrides getBasePackage() to return 'com.arc_e_tect.sedr.example.jacoco.marker'.
Verified behaviour
------------------
Running './gradlew test' (after publishToMavenLocal on sedr-library) produces
exactly one violation:
Method com.arc_e_tect.sedr.example.jacoco.marker.NonCompliantService.stop()
uses @ExcludeFromJacocoGeneratedCodeCoverage without a justification
CompliantService is not mentioned in the output.
…ADME
What changed
------------
README.adoc
- Correct 'Latest version' table entry from 0.2.1 to 0.2.6.
- Add section 'Enforcing the justification convention with ArchUnit':
- Explains the purpose of the test-fixtures artifact.
- Shows how to declare testImplementation(testFixtures(...)) in Kotlin
and Groovy DSL.
- Explains the need for junit-jupiter-engine and junit-platform-launcher
as testRuntimeOnly dependencies with version examples.
- Shows the one-method subclass pattern for CoverageExclusionConventionsTest.
- Side-by-side compliant vs. non-compliant annotation usage examples.
- Add section 'Example project':
- Links to examples/sedr-library/jacoco-marker/.
- Table describing each source file and its role.
- Two-step instructions (publishToMavenLocal then ./gradlew test).
- States the expected violation output (NonCompliantService named;
CompliantService absent).
Owner
Author
|
🎉 This PR is included in version 0.3.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What's Changed
Docs: Updated
README.adoc:test-fixtures.jacoco-marker) with usage details.Feature: Introduced
test-fixturesartifact for ArchUnit conventions:@ExcludeFromJacocoGeneratedCodeCoverageannotations.AbstractCoverageExclusionConventionsTestwith extendable functionality for custom scenarios.Feature: Added standalone
jacoco-markerexample project:@ExcludeFromJacocoGeneratedCodeCoverageand reusable tests.Fix: Corrected invalid annotation syntax in Javadoc of
ExcludeFromJacocoGeneratedCodeCoverageto avoid errors when referenced.Purpose
This pull request enhances usability by: