Sprint 11 Testplan — Verifying the Test Suite Quality
Date: 2026-06-15
Sprint Theme: Quality Foundation — Backend Test Coverage
Author: Patrick Plate / Roo (Architect)
Status: Draft v1
Basis: cannamanage-sprint11-plan.md
Overview
This is a meta-testplan: since Sprint 11's deliverable IS test code, this document defines how we verify that the test suite itself is correct, complete, and maintainable.
Verification Strategy
Test Quality Criteria
QC-01: All Tests Pass
| ID |
Check |
Pass Condition |
| QC-01a |
mvn test -pl cannamanage-service |
Exit code 0 |
| QC-01b |
mvn test -pl cannamanage-api |
Exit code 0 |
| QC-01c |
mvn verify (full project) |
Exit code 0, JaCoCo check passes |
| QC-01d |
No @Disabled annotations |
0 disabled tests |
QC-02: Coverage Thresholds
| ID |
Package |
Minimum |
Measurement |
| QC-02a |
Overall project |
≥80% lines |
JaCoCo aggregate |
| QC-02b |
de.cannamanage.service.bankimport |
≥90% lines |
JaCoCo per-package |
| QC-02c |
de.cannamanage.service.FinanceService |
≥90% lines |
JaCoCo per-class |
| QC-02d |
de.cannamanage.api.security |
≥80% lines |
JaCoCo per-package |
| QC-02e |
de.cannamanage.service (compliance classes) |
≥90% lines |
JaCoCo per-class |
| QC-02f |
de.cannamanage.service (business logic) |
≥75% lines |
JaCoCo per-package |
QC-03: Test Isolation
| ID |
Check |
Pass Condition |
| QC-03a |
Tests run in any order |
mvn test -Dsurefire.runOrder=random passes |
| QC-03b |
Tests are independent |
No shared mutable state between tests |
| QC-03c |
No external dependencies in unit tests |
Unit tests pass without Docker/network |
| QC-03d |
Integration tests use Testcontainers |
No hardcoded DB connection strings |
QC-04: Test Quality (Structural)
| ID |
Check |
Pass Condition |
| QC-04a |
Meaningful assertions |
No assertTrue(true) or bare assertNotNull |
| QC-04b |
Each test has exactly one reason to fail |
One logical assertion per test |
| QC-04c |
Test naming follows convention |
test<Method>_<Scenario>_<Expected> or @DisplayName |
| QC-04d |
Given-When-Then structure |
Clear arrange/act/assert sections |
| QC-04e |
Edge cases covered |
Null, empty, boundary, error paths |
| QC-04f |
No hardcoded UUIDs shared between tests |
Each test creates its own test data |
QC-05: Financial Precision
| ID |
Check |
Pass Condition |
| QC-05a |
All amounts tested in cents (Integer) |
No floating-point in financial assertions |
| QC-05b |
Rounding edge cases covered |
e.g., 1/3 split, odd-cent distribution |
| QC-05c |
Ledger entries always sum to zero |
Every credit has offsetting debit |
| QC-05d |
Void operation creates exact reversal |
Original + reversal = 0 |
QC-06: Security Test Completeness
| ID |
Check |
Pass Condition |
| QC-06a |
XXE attack rejected |
Camt053Parser doesn't process external entities |
| QC-06b |
Path traversal sanitized |
../ removed from filenames |
| QC-06c |
Token expiry enforced |
Expired JWT returns 401 |
| QC-06d |
Tenant isolation holds |
Cross-club access returns 403 |
| QC-06e |
Rate limiter blocks after threshold |
6th attempt blocked |
Mutation Testing (Spot-Check)
To verify tests actually catch bugs (not just increase coverage), run mutation testing on 3 critical classes:
| Class |
Tool |
Target Mutation Score |
PaymentMatchingService |
PITest (manual spot-check) |
≥70% mutants killed |
FinanceService |
PITest (manual spot-check) |
≥70% mutants killed |
Mt940Parser |
PITest (manual spot-check) |
≥70% mutants killed |
PITest command (optional — stretch goal):
Traceability Matrix
Every plan phase maps to a verification:
| Plan Phase |
Test Class |
QC Checks |
| Phase 1 (Infrastructure) |
N/A — verified by Phase 2+ tests running |
QC-01c |
| Phase 2 (Financial) |
FinanceServiceTest, PaymentMatchingServiceTest, Mt940ParserTest, Camt053ParserTest, CsvBankParserTest, BankImportServiceTest, RetentionServiceTest, ReportGeneratorServiceTest, EurReportGeneratorTest, AnnualAuthorityReportGeneratorTest |
QC-02b, QC-02c, QC-05 |
| Phase 3 (Business) |
AssemblyServiceTest, EventServiceTest, ForumServiceTest, InfoBoardServiceTest, NotificationDispatchServiceTest |
QC-03, QC-04 |
| Phase 4 (Security) |
JwtServiceTest, LoginRateLimiterTest, TenantFilterAspectTest, DocumentServiceTest |
QC-02d, QC-06 |
| Phase 5 (Integration) |
BankImportIntegrationTest, FinanceIntegrationTest, AssemblyIntegrationTest, ReportIntegrationTest |
QC-01b, QC-03d |
| Phase 6 (CI) |
Full mvn verify |
QC-01c, QC-02a |
Test Execution Order
Acceptance Criteria for Sprint 11 Completion
| # |
Criterion |
Verified By |
| 1 |
mvn verify passes with 0 failures |
CI or local run |
| 2 |
JaCoCo reports ≥80% overall line coverage |
JaCoCo HTML report |
| 3 |
Financial/compliance packages at ≥90% |
JaCoCo per-package |
| 4 |
Security packages at ≥85% (incl. GlobalExceptionHandler) |
JaCoCo per-package |
| 5 |
Infrastructure (Schedulers + Notifications) at ≥70% |
JaCoCo per-package |
| 6 |
No @Disabled or @Ignored tests |
grep scan |
| 7 |
Tests pass in random order |
surefire.runOrder=random |
| 8 |
Integration tests work with fresh Testcontainers |
Clean Docker environment |
| 9 |
≥345 total backend tests (from ~20) |
Surefire report count |
| 10 |
Build time stays under 7 minutes total |
Maven timing output (forkCount=2) |
| 11 |
Mutation testing spot-check ≥70% on 3 critical classes |
PITest results |
Risk Mitigation
| Risk |
Mitigation |
Verification |
| Flaky tests (intermittent failures) |
No shared state, deterministic data |
Random order pass (QC-03a) |
| Slow integration tests |
Tag with @Tag("integration"), run separately |
Split fast/slow in CI |
| Tests pass but don't catch bugs |
Mutation testing spot-check |
PITest on 3 classes |
| Coverage gaming (meaningless assertions) |
QC-04 structural quality checks |
Code review of tests |
| Docker unavailable in CI |
Testcontainers cloud support OR separate CI stage |
CI pipeline design |