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.

2025 in Review: The Year .NET Stopped Lying to Itself

.NET 10 Testing: Microsoft Finally Fixed the Test Runner (Mostly)
Microsoft.Testing.Platform, bringing SDK-integrated testing with faster discovery, consistent behavior across environments, and explicit configuration contracts. But it requires .NET 10, breaks old test adapters, and demands CI pipeline discipline. Here’s what actually changes, who should migrate now, and who should wait.
Tests Are Lying
It begins like many stories in software: a well-intentioned developer joining a project, determined to do things properly. You arrive at a codebase that has grown organically, perhaps even chaotically. You decide you will bring order. You set up unit testing, you configure continuous integration, you measure code coverage. You write dozens or hundreds of tests. Every public method is touched, every branch is at least executed. The dashboard lights up green. You feel, quite frankly, on top of things.
Then one day, production breaks under your watch

TUnit — A Pragmatic Evaluation for .NET Teams

How to Use Copilot Without Becoming Its Puppet
In a previous article, we laid it out – unfiltered: Copilot turns junior devs into syntax secretaries.
Not because it’s evil. But because it removes friction before understanding.
It gives you working code before you know what working even means. It creates the illusion of progress, while slowly eroding the very skills that define a software engineer: reasoning, decision-making, and technical ownership.