piotrek
piotrek

Reputation: 14550

How to test flyway migration?

Usually migration script is simple like adding new column or so and if applications if deployed then everything is ok. but sometimes there is some complex logic involved that should be tested. what is the recommended approach?

Upvotes: 6

Views: 9676

Answers (2)

selalerer
selalerer

Reputation: 3924

My answer is relevant to the technologies I use: Spring Boot and Maven. I hope it helps.

I use Zonky. I add these dependencies (add the latest version in <version></version> tags or in dependencyManagement):

<dependency>
  <groupId>org.flywaydb</groupId>
  <artifactId>flyway-core</artifactId>
</dependency>
<dependency>
  <groupId>io.zonky.test</groupId>
  <artifactId>embedded-database-spring-test</artifactId>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>io.zonky.test</groupId>
  <artifactId>embedded-postgres</artifactId>
  <scope>test</scope>
</dependency>

To the Java test class I add these annotations:

@SpringBootTest(classes = {MyApplication.class})
@AutoConfigureEmbeddedDatabase(provider = AutoConfigureEmbeddedDatabase.DatabaseProvider.ZONKY,
        type = AutoConfigureEmbeddedDatabase.DatabaseType.POSTGRES,
        refresh = AutoConfigureEmbeddedDatabase.RefreshMode.BEFORE_EACH_TEST_METHOD)
public class MyTestClass

The rest of it what Axel answered above. I add a migration to to src/test/resource/db/migration/ folder with a version number that comes before the migration I want to test.

insert into user(id,name) values(100, 'OldUserNameFormat');

Then I add a test to MyTestClass:

public class MyTestClass {

  @Autowired
  private UserRepository userRepository;

  @Test
  public void testOldUserMigration() {
      User user = userRepository.findById(100).orElseThrow();
      assertEquals("NewUserNameFormat",user.getName());
  }
}

If the migration has some SQL error that DB detects the test (and all other @SpringBootTest that run flyway) will fail at initialization. The Java code test will also check that the result of the migration is as expected, though this might be later broken by further migrations since the Java code runs after all the migrations are done, but when it will, it will be too late to fix this migration anyway, assuming it already ran in production environments and at this time the test is not relevant anymore and can be removed.

Upvotes: 0

Axel Fontaine
Axel Fontaine

Reputation: 35169

Have a separate DB for testing. Migrate it as part of every build and run tests against it. You can also populate it with extra test data as you desire by including a second location for test data migrations.

Main Location:

  • V1__Initial.sql
  • V2__More_changes.sql
  • V3__Complex_logic.sql

Test data location:

  • V2.1__Test_data.sql

You can then call flyway.clean() and flyway.migrate() in a test before asserting whether the test data got transformed correctly.

Upvotes: 11

Related Questions