How to Run Database Migrations Before Testcontainers Tests
Run your real migrations against the Testcontainers database first so tests exercise the production schema, not an ad-hoc one.
After the container starts, point your migration tool (Flyway, Liquibase, Alembic, EF Core) at the mapped JDBC URL and apply migrations. For simple cases, the module can run an init script at startup instead.
Steps
- Start the database container and read its JDBC URL.
- Run migrations against that URL before any test executes.
- Or attach an init script with
.withInitScript(...)for lightweight schema setup. - Fail the run if migration fails so tests do not run on a bad schema.
Flyway example
MigrationIT.java
@BeforeAll
static void migrate() {
Flyway.configure()
.dataSource(db.getJdbcUrl(), db.getUsername(), db.getPassword())
.locations("classpath:db/migration")
.load()
.migrate();
}Init script alternative
InitScriptIT.java
static PostgreSQLContainer<?> db =
new PostgreSQLContainer<>("postgres:16-alpine")
.withInitScript("schema.sql");Gotchas
- Run migrations once per shared container, not per test, to avoid repeated work.
- Keep migration files identical to production so the test schema does not drift.