testing
Unified testing strategy for the .NET 8 WPF widget host app - domain unit tests, ViewModel tests, integration tests, and test infrastructure. Use when writing tests for entities, ViewModels, repositories, or setting up test harnesses.
When & Why to Use This Skill
This Claude skill provides a comprehensive and unified testing strategy specifically designed for .NET 8 WPF applications. It establishes clear patterns and infrastructure for domain logic validation, ViewModel behavior testing, and repository integration, ensuring high-quality code through a structured 'Definition of Done' and standardized naming conventions.
Use Cases
- Case 1: Implementing deterministic unit tests for domain entities and business logic to ensure core invariants and validation rules are consistently met.
- Case 2: Testing WPF ViewModels and UI commands using specialized test harnesses to verify state transitions and property changes without requiring a full WPF runtime.
- Case 3: Creating robust integration tests for data access layers using isolated in-memory or temporary databases to validate repository CRUD operations and migrations.
- Case 4: Standardizing test infrastructure and naming conventions across a development team to maintain a clean, scalable, and professional test suite.
| name | testing |
|---|---|
| description | Unified testing strategy for the .NET 8 WPF widget host app - domain unit tests, ViewModel tests, integration tests, and test infrastructure. Use when writing tests for entities, ViewModels, repositories, or setting up test harnesses. |
Testing
Overview
Comprehensive testing strategy covering domain logic, UI behavior, and data access with clear patterns for each layer.
Test Project Structure
| Project | Focus | Dependencies |
|---|---|---|
3SC.Domain.Tests |
Entities, value objects, domain logic | Domain only |
3SC.UI.Tests |
ViewModels, commands, converters | UI + mocks |
3SC.Infrastructure.Tests |
Repositories, data access | Infrastructure + test DB |
1. Domain Tests
Scope
- Entity invariants and behavior
- Value object equality and validation
- Domain service logic
- Pure application use cases
Rules
- No infrastructure dependencies
- No UI dependencies
- Deterministic (no DateTime.Now, no random)
- Fast (< 1 second per test)
Patterns
[Fact]
public void Widget_WithNullName_ThrowsArgumentException()
{
Assert.Throws<ArgumentException>(() => new Widget(null!, "key"));
}
2. ViewModel Tests (UI Tests)
Scope
- Command execution and can-execute
- Observable property changes
- State transitions
- Validation logic
Rules
- Use NoOp/mock service implementations
- No WPF runtime dependency
- Test via
WidgetTestHarnesswhen services needed
Patterns
[Fact]
public void Command_WhenExecuted_UpdatesProperty()
{
var vm = new MyViewModel(new FakeService());
vm.SomeCommand.Execute(null);
Assert.True(vm.IsCompleted);
}
3. Integration Tests (Data Tests)
Scope
- Repository CRUD operations
- Query behavior
- Migration validation
- Transaction handling
Rules
- Isolated DB per test (in-memory or temp file)
- Migrations applied before tests
- Explicit data seeding (no shared fixtures)
- Proper cleanup in Dispose
Patterns
public class WidgetRepositoryTests : IDisposable
{
private readonly AppDbContext _context;
public WidgetRepositoryTests()
{
_context = DbTestFactory.CreateInMemory();
}
[Fact]
public async Task Add_PersistsWidget()
{
var repo = new WidgetRepository(_context);
await repo.AddAsync(new Widget("Test", "key"));
Assert.Single(await repo.GetAllAsync());
}
public void Dispose() => _context.Dispose();
}
Definition of Done (DoD)
Domain Tests
- New domain logic has corresponding unit tests
- Tests cover happy path + at least one edge/error case
- Tests are deterministic
- Tests run in under 1 second each
ViewModel Tests
- Commands tested for execute and can-execute behavior
- State changes tested through observable property assertions
- Test harness updated when new services are added
Integration Tests
- Each test gets isolated DB instance
- Migrations applied automatically before tests
- Repository tests cover CRUD + edge cases
- Tests clean up resources in Dispose
Test Infrastructure
WidgetTestHarness
Located in 3SC.UI.Tests/WidgetTestHarness.cs - provides NoOp implementations of all widget services for isolated ViewModel testing.
DbTestFactory
Located in 3SC.Infrastructure.Tests/DbTestFactory.cs - creates isolated in-memory or file-based test databases.
Naming Conventions
{MethodName}_{Scenario}_{ExpectedResult}
Examples:
GetById_WithValidId_ReturnsWidgetAdd_WithDuplicateKey_ThrowsExceptionExecute_WhenDisabled_DoesNotRun
Anti-Patterns
- ❌ Tests depending on other tests' data
- ❌ Shared mutable state across tests
- ❌ Testing private methods directly
- ❌ Fragile UI selectors in ViewModel tests
- ❌ DateTime.Now or Random in tests