Testing Overview
SimpleModule uses a layered testing strategy: unit tests for isolated logic, integration tests for HTTP endpoints with a real application pipeline, and end-to-end tests for browser-based flows.
Test Stack
| Library | Purpose |
|---|---|
| xUnit.v3 | Test framework |
| FluentAssertions | Expressive assertions |
| Bogus | Fake data generation |
| NSubstitute | Mocking / test doubles |
| Microsoft.AspNetCore.Mvc.Testing | In-process integration testing |
| Playwright | Browser-based E2E testing |
Project Conventions
Test projects follow a consistent naming and location pattern:
| Type | Location | Naming |
|---|---|---|
| Module tests | modules/<Name>/tests/<Name>.Tests/ | <Name>.Tests.csproj |
| Shared infrastructure | tests/SimpleModule.Tests.Shared/ | Fixtures, fakes, generators |
| E2E tests | tests/e2e/ | Playwright specs |
Each module test project is organized into subdirectories:
modules/Products/tests/Products.Tests/
Unit/
ProductServiceTests.cs
CreateRequestValidatorTests.cs
Integration/
ProductsEndpointTests.csRunning Tests
bash
# Run all .NET tests
dotnet test
# Run a single test class
dotnet test --filter "FullyQualifiedName~ProductServiceTests"
# Run a single test method
dotnet test --filter "FullyQualifiedName~CreateProductAsync_CreatesAndReturnsProduct"
# Run E2E tests
npm run test:e2e
# Run E2E tests with UI
npm run test:e2e:uiTest Naming
Test methods use underscore-separated names following the pattern:
Method_Scenario_ExpectedFor example:
GetProductByIdAsync_WithExistingId_ReturnsProductCreateProduct_WithCreatePermission_Returns201Validate_WithEmptyName_ReturnsError
This convention is enforced by .editorconfig which suppresses the CA1707 naming rule in test projects.
CI Strategy
CI runs tests against two database providers:
- SQLite in-memory -- fast, used for all local development and the primary CI pass
- PostgreSQL -- used for integration verification in CI to catch provider-specific issues
The SimpleModuleWebApplicationFactory automatically uses SQLite in-memory with a shared connection kept open for the lifetime of the test run.
Next Steps
- Unit tests -- testing services, validators, and event handlers in isolation
- Integration tests -- testing HTTP endpoints end-to-end with
WebApplicationFactory - E2E tests -- browser-based testing with Playwright