|
|
||
|---|---|---|
| .. | ||
| GoodWood.Tests | ||
| README.md | ||
README.md
Koogle Test Suite
Comprehensive testing infrastructure for the Koogle club management application.
Test Projects
Koogle.Tests
Main test project containing:
- Unit Tests: Domain entities, services, Fluxor reducers
- Integration Tests: API endpoints, database operations
- Component Tests: bUnit tests for Blazor components
- Performance Tests: Response time and memory allocation tests
Koogle.E2E
End-to-end tests using Playwright:
- Authentication flow tests
- User journey tests
- UI interaction tests
Running Tests
All Tests
dotnet test test/Koogle.Tests
Specific Test Categories
# Unit tests only
dotnet test test/Koogle.Tests --filter "FullyQualifiedName~Unit"
# Integration tests only
dotnet test test/Koogle.Tests --filter "FullyQualifiedName~Integration"
# Component tests only
dotnet test test/Koogle.Tests --filter "FullyQualifiedName~Components"
# Performance tests only
dotnet test test/Koogle.Tests --filter "FullyQualifiedName~Performance"
E2E Tests
Before running E2E tests:
- Install Playwright browsers:
pwsh test/Koogle.E2E/bin/Debug/net9.0/playwright.ps1 install
- Start the application:
dotnet run --project src/Koogle.Web
- Run E2E tests:
E2E_BASE_URL=https://localhost:7001 dotnet test test/Koogle.E2E
Environment variables:
E2E_BASE_URL: Application URL (default: https://localhost:7001)E2E_HEADLESS: Set to "false" to see browser (default: headless)E2E_SLOWMO: Milliseconds to slow down operations for debugging
Test Coverage
dotnet test test/Koogle.Tests --collect:"XPlat Code Coverage"
Report location: test/Koogle.Tests/TestResults/*/coverage.cobertura.xml
Test Structure
test/
├── Koogle.Tests/
│ ├── Common/ # Shared test utilities
│ │ ├── TestDataGenerator.cs # Bogus-based test data
│ │ └── MockExtensions.cs # Mock setup helpers
│ │
│ ├── Unit/
│ │ ├── Domain/ # Entity tests
│ │ ├── Services/ # Service unit tests
│ │ └── Store/ # Fluxor reducer tests
│ │
│ ├── Integration/ # API & DB integration tests
│ │
│ ├── Components/ # bUnit Blazor tests
│ │
│ └── Performance/ # Performance benchmarks
│
└── Koogle.E2E/
├── PageObjectModels/ # Page abstractions
└── *Tests.cs # E2E test files
Test Patterns
AAA Pattern
All tests follow Arrange-Act-Assert:
[Fact]
public async Task GetByIdAsync_ReturnsClub_WhenExists()
{
// Arrange
var club = TestDataGenerator.CreateClub();
_repositoryMock.SetupGetByIdAsync(club.Id, club);
// Act
var result = await _sut.GetByIdAsync(club.Id);
// Assert
result.Should().NotBeNull();
result!.Id.Should().Be(club.Id);
}
Theory-Based Testing
For parameterized tests:
[Theory]
[InlineData(ExpenseCalculation.None)]
[InlineData(ExpenseCalculation.Average)]
[InlineData(ExpenseCalculation.Maximum)]
public async Task CreateAsync_HandlesAllExpenseCalculationTypes(ExpenseCalculation calc)
{
// Test each enum value
}
State Immutability Testing
For Fluxor reducers:
[Fact]
public void Reducers_DoNotMutateOriginalState()
{
var originalState = ClubState.Initial with { Clubs = [...] };
var originalCount = originalState.Clubs.Count;
ClubReducers.OnDeleteClubSuccess(originalState, action);
originalState.Clubs.Should().HaveCount(originalCount);
}
Writing New Tests
1. Use TestDataGenerator
var club = TestDataGenerator.CreateClub(
name: "My Club",
expenseCalculation: ExpenseCalculation.Average);
2. Use MockExtensions
_repositoryMock
.SetupGetAllAsync(clubs)
.SetupAddAsync();
3. Use FluentAssertions
result.Should().NotBeNull();
result.Should().HaveCount(3);
result.Should().Contain(x => x.Name == "Club A");
Dependencies
| Package | Purpose |
|---|---|
| xUnit | Test framework |
| FluentAssertions | Readable assertions |
| Moq | Mocking |
| bUnit | Blazor component testing |
| Bogus | Test data generation |
| AutoFixture | Object creation |
| Microsoft.AspNetCore.Mvc.Testing | Integration testing |
| Microsoft.Playwright | E2E testing |
| Coverlet | Code coverage |
| RichardSzalay.MockHttp | MockHttp for HttpClient |