# .NET Testing Techniques You Didn’t Know You Needed - Dante De Ruwe - NDC Copenhagen 2026

## Executive summary

This talk explores advanced .NET testing techniques designed to improve test effectiveness and build confidence in code quality beyond basic unit tests. Key methods include Property-Based Testing (PBT) for generating vast input variations, Snapshot Testing for tracking complex output changes over time, and Mutation Testing for verifying if existing tests are actually capable of catching bugs. The speaker emphasizes that the goal is not just to write many tests, but to write fewer, highly effective tests.

## Key takeaways

- Test Reliability vs. Code Trust: Tests should be viewed as a 'parachute'—they must have no holes. A failing test when requirements haven't changed indicates a bug; passing when the code changes suggests incomplete coverage or potential issues.
- Randomized and Property-Based Testing (PBT): Instead of relying solely on example cases, PBT defines mathematical properties that the code must always satisfy (e.g., a + b = b + a). This is crucial for complex structures or when edge case enumeration is impossible.
- Snapshot Testing: This technique captures and saves the output of a function (the 'snapshot'). Subsequent test runs fail if the output changes unexpectedly, making it ideal for verifying API contracts (like OpenAPI specs) or complex data structures without writing explicit assertions for every field.
- Mutation Testing: This advanced technique introduces small bugs (mutations) into the code and checks if the existing test suite fails. A high mutation score indicates that tests are effective at catching subtle errors, debunking false confidence from high line coverage metrics.

## Technical details

- Property-Based Testing (PBT): PBT allows defining properties (like commutativity or associativity for addition) rather than specific input/output pairs. Tools like `fscheck` (a .NET package inspired by QuickCheck) facilitate this, generating random parameters to test the code's adherence to mathematical rules.
- Snapshot Testing / Golden Master Testing: Used for complex data or API contracts (e.g., OpenAPI specs). The first run saves the output structure; subsequent runs fail if the generated output deviates, ensuring unintended changes are caught without writing exhaustive assertions.
- Mutation Testing: A quality metric that measures test effectiveness by introducing controlled bugs (mutants) into the source code. The 'mutation score' is the percentage of mutants killed by tests; a low score means tests are ineffective, even if coverage is high.
- Flaky Tests Mitigation: To prevent flaky tests, developers should use deterministic test data (by seeding random generators) and employ large sample sizes when running randomized tests. When dealing with time-sensitive code, always work with UTC and use abstractions like `ISystemClock`.

## Practical implications

- Integrate mutation testing into nightly CI runs to validate test suite effectiveness.
- Use snapshot testing for API contract validation (e.g., OpenAPI specs) to prevent unintended breaking changes across teams.
- When writing tests for complex logic or data structures, prioritize defining mathematical properties over listing every possible example case.
- Be cautious with time zone handling; always map and store dates/times in UTC to avoid flaky tests related to Daylight Saving Time transitions.

## Topics

Software Testing, Unit Testing, Quality Assurance, .NET Development, Test Driven Development (TDD), Build Engineering

Source: https://www.youtube.com/watch?v=LHKWUUFCqms
