Spring boot testing with liquibase fails
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
When Spring Boot tests fail around Liquibase, the failure is usually not Liquibase itself but the relationship between the test database, the migration scripts, and the test application context. In other words, the changelog is being executed in an environment that does not behave like the one your application normally expects.
Understand Why Liquibase Runs During Tests
By default, Spring Boot starts Liquibase when the application context starts. That includes many integration tests, because from Spring’s point of view a test context is still an application context that needs a schema.
This is helpful when you want realistic tests. It becomes frustrating when:
- the test database differs from production
- the changelog uses SQL that the test database does not support
- multiple test classes share and mutate the same schema
- a slice test loads Liquibase even though the schema is irrelevant
The first step is to decide which kind of test you are writing. Integration tests usually should run migrations. Lightweight unit or slice tests often should not.
Make the Test Database Match the Changelog
One of the most common causes of Liquibase failures is using H2 for tests while the changelog was written with PostgreSQL or MySQL-specific SQL in mind. A migration that passes in production can fail instantly in tests because the database engine is different.
A more reliable pattern is to use the same database engine in tests through Testcontainers:
This gives Liquibase the same database dialect your real application expects, which eliminates a large class of "works in prod, fails in test" problems.
Keep the Test Profile Configuration Explicit
If you do use a dedicated test profile, make sure the datasource and Liquibase settings are aligned. A common pattern in application-test.yml is:
The important part is consistency. If your test datasource points to one database but Liquibase is configured implicitly against something else, the startup failure can look mysterious even though the root cause is simply configuration drift.
It is also worth checking whether your tests are reusing a dirty database between runs. Liquibase may behave differently when the changelog table already exists or when previous test data has altered the expected schema state.
Disable Liquibase Only for Tests That Do Not Need It
Not every test should pay the price of full schema migration. If you are running a controller slice test or a unit-style Spring test that does not touch the database, disable Liquibase for that test scope:
This is a good fix when the test is not supposed to care about persistence at all.
What you should avoid is disabling Liquibase globally just to silence failures in integration tests. That gives you fast green tests and a false sense of safety, because the schema used in production is no longer being validated in the test environment.
Common Pitfalls
The biggest mistake is testing against H2 while the changelog contains production-database-specific SQL. That mismatch causes many avoidable Liquibase failures.
Another issue is using one shared test database across many tests without controlling isolation. A schema altered by one test run can affect the next one in surprising ways.
Developers also sometimes disable Liquibase for all tests instead of deciding which tests actually need migrations. That removes useful coverage from integration tests.
Finally, when a migration fails, read the original SQL or dialect error carefully. The top-level Spring Boot startup failure often hides the real database-specific reason several causes down the stack trace.
Summary
- Liquibase runs during many Spring Boot tests because the test context starts like a real application context.
- Failures are often caused by database-dialect mismatches, especially when using H2 against production-specific changelogs.
- Testcontainers is often the most reliable fix for integration tests because it matches the real database engine.
- Keep test datasource and Liquibase configuration explicit and consistent.
- Disable Liquibase only for tests that genuinely do not need schema migrations.
Related reading
- Spring CrudRepository findByInventoryIds(List<Long> inventoryIdList) - equivalent to IN clause
- Spring Data JPA - could not initialize proxy - no Session - With Methods marked as transactional
- Spring Data JPA Unable to locate Attribute with the given name
- Spring Data JPA without Spring Boot
- Spring boot Unable to start embedded Tomcat servlet container
- Spring Boot Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean
- Spring Boot Unit Test Autowired
- Spring Boot Unit Test ignores logging.level

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.