Software Testing and Quality Assurance
Tests usually pass for reasons unrelated to whether the code under test actually works. Line coverage reports green, the CI dashboard is clean, and a bug ships to production through a code path every test technically executed. The articles in this collection start from that observation: the value of a test is what it would catch on failure, not what it asserts on success.
Mutation testing is the recurring theme because it answers the question coverage cannot: if the implementation changes in a small, semantically meaningful way, do any tests notice? Stryker.NET introduces deliberate faults — flipping > to >=, replacing return values, removing method calls — and reports which mutations survive. Surviving mutations are blind spots dressed up as test coverage, and the surprise during the first run is rarely small.
TimeProvider adoption is the second recurring topic. DateTime.UtcNow is a hidden dependency that makes deterministic testing impossible and silently produces bugs that only surface at midnight, on the last day of the month, or across daylight saving transitions. .NET 8 shipped the abstraction in 2023; most codebases still ignore it. The articles cover how to introduce TimeProvider to legacy code without rewriting half the project and what tests become possible once time is no longer hardcoded.
Integration tests get specific attention because the failure mode is different. Unit tests prove that a method does what its author intended; integration tests prove that the wiring around it still holds. The trade-offs between in-memory fakes, Testcontainers, and full deployed environments are covered with the costs named — test execution time, flakiness budgets, and the maintenance overhead each option implies.
A separate cluster examines what tests claim to prove versus what they actually prove: contract tests that miss the contracts that matter, snapshot tests that lock in bugs as expected output, and the coverage thresholds that look rigorous in CI but mean nothing in production.

Stop Pretending TimeProvider Doesn't Exist

Security Tests That Prove Themselves

"Just Delete the User": Famous Last Words Before the GDPR Audit

Green Dashboard, Dead Application
Your application just crashed in production. Azure App Service kept routing traffic to the failing instance for ninety seconds. Users saw timeouts. Your monitoring dashboard stayed green because the web server responded with HTTP 200 while the database connection pool was exhausted.
I’ve watched this exact scenario play out at three different organizations in the past year. Each time, the post-mortem revealed the same root cause: health checks that verified the process was breathing without checking whether it could actually do its job. ISO/IEC 27001 Control A.17.2.1 exists precisely for this reason—availability is a security control, not an operational afterthought.
