DKNet

Testing & Coverage Strategy

DKNet’s test suite uses xUnit with Shouldly assertions and TestContainers.MsSql for integration tests, so persistence is exercised against a real SQL Server rather than an in-memory provider. Every package has a sibling *.Tests project, and coverage gates are enforced in CI to keep the framework reliable.

Conventions

Why real databases

Integration tests run against TestContainers.MsSql (Docker required) rather than EF Core InMemory, because the in-memory provider masks SQL-specific behavior. This is what validates features such as Specifications, its Dynamic Predicate Builder (including the mandatory .AsExpandable() expansion), and DataAuthorization’s query-filter translation. Never run these tests locally on an ARM device (no mssql/server ARM image) — verify via the remote-tests.yml GitHub Actions workflow instead (see the root CLAUDE.md).

Coverage targets

Area Target
Core libraries 99% line
EfCore libraries 95% line
Service libraries 90% line
CI gate (overall) 80% line

The primary CI pipeline (.github/workflows/build-test-coverage.yml) restores, builds in Release, runs tests with coverage collection, runs SonarCloud analysis, enforces the 80% gate, and comments coverage on PRs. Tests should encode why behavior matters, exercising the domain rules described in Architecture and the persistence behaviors built on Specifications.


Current status