Migration tests need to prove more than compilation. They need to show that the new application still honours important contracts and that a test failure is reproducible without damaging shared data.
The test host is part of the architecture
WebApplicationFactory<Program> creates an application host for integration tests. The fixture can replace connection strings, choose the Development environment, disable external secret providers, and configure cookies for a test server.
That makes the test host a controlled version of the real composition root.
Isolate the database
Each test fixture should have an isolated database name or database instance. The fixture owns creation, baseline roles, required reference records, and cleanup. Tests should not depend on a developer’s working database or on the order in which another test ran.
SQLite can be useful for fast local integration tests, but provider differences still matter. A query that succeeds in SQLite may behave differently in SQL Server, so important production-specific queries need an appropriate test strategy too.
Test workflows, not implementation trivia
The valuable tests follow user-visible flows:
- invitation acceptance;
- development or session expiry behaviour;
- role-sensitive visibility;
- create/edit operations;
- database and validation failures;
- end-to-end AJAX or partial-view responses.
These tests protect the contracts that a migration is meant to preserve.
Keep browser tests honest
A framework test host is not automatically a real TCP server. Browser tests that require a reachable address need a standalone host or a separately started application. Document that distinction so a failing browser test is not misdiagnosed as an application route failure.
The lesson
Good migration tests create confidence at the boundaries: HTTP, authentication, database, and browser behaviour. They also make failures cheap to reproduce by owning their environment and data lifecycle.