Testing strategies, frameworks, and best practices for .NET applications.
| Layer |
Tests |
Speed |
Scope |
| Unit |
70% |
Fast |
Single function/class |
| Integration |
20% |
Medium |
Component interactions |
| E2E |
10% |
Slow |
Full user workflows |
| Type |
Purpose |
Use Case |
| Dummy |
Fill parameters |
Required but unused dependency |
| Stub |
Provide canned answers |
Repository returning test data |
| Mock |
Verify interactions |
Assert email service was called |
| Fake |
Working implementation |
In-memory database |
| Spy |
Record calls |
Track method invocations |
| Framework |
Style |
Best For |
| xUnit |
Modern, opinionated |
New .NET projects |
| NUnit |
Attribute-based |
Full-featured testing |
| MSTest |
Microsoftβs framework |
VS integration |
| Playwright |
Browser automation |
E2E testing |
- Test behavior, not implementation - Focus on what, not how
- Keep tests fast and independent - No shared state between tests
- Use meaningful test names -
MethodName_Scenario_ExpectedResult
- Follow the testing pyramid - More unit tests, fewer E2E tests
- Use realistic test data - Builders and fixtures for consistency
- Mock at boundaries - External services, not internal classes