Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integration Testing with Flyway

I'm using Flyway to handle the database migration. Everything is working fine: the default location of the migration files is:

main/resource/db/migration/V1...

I am running integration tests and my setup uses an separate database schema for integration, which I would like to manage with flyway as well. The integration tests, though, are located in the test folder (not main). When the Flyway bean executes migrate(), it doesn't find the migration files because they are in the main folder. If I put the migration files in test/resource/db/migration/V1... it works.

I really don't want to have to copy these file into the test resource folder, so I don't have to maintain both. Is there a way to force Flyway to use the same migration files for the integration test as for the normal app?

like image 803
Johny19 Avatar asked Sep 30 '15 16:09

Johny19


People also ask

What is Flyway integration?

Flyway is a version control application to evolve your Database schema easily and reliably across all your instances. To learn more about Flyway, you can use the link − www.flywaydb.org. Many software projects use relational databases.

How does Flyway integrate with Jenkins?

Open Jenkins click the Jenkins item that used to initialize the Flyway instance, then click “Configure”. Scroll down until the Build section, then change the Invoke Flyway form, change InstallationName and Database URL into brand new Flyway instance that needs to be initialized. Click the “Save” button to save it.

What is Flyway used for?

Flyway is an open-source tool, licensed under Apache License 2.0, that helps you implement automated and version-based database migrations. It allows you to define the required update operations in an SQL script or as Java code.


2 Answers

I assume you're using Maven? For unit tests both test/resources and main/resources get loaded into the classpath. test/resources files usually take precedence, as they are placed higher up in the classpath - if I recall correctly. Regardless, I don't recommend you do this.

Instead I recommend you make an entirely different Flyway configuration for integration testing that is in a separate directory (ie test/resources/integration/migration/) and runs after the main/resources/db/migration default one.

Even then it might be easier to not use Flyway to setup your integration data fixtures and instead use some other database data loading tools like DbUnit (I'm sure there are others).

like image 134
Adam Gent Avatar answered Sep 19 '22 10:09

Adam Gent


Another hint: For Database Unit Testing you can also use the Flyway Test Extension see https://github.com/flyway/flyway-test-extensions.

The extensions have also a addon for DbUnit integration for data loading so you got control for database setup in your test environment.

Adams answer is correct do not copy your real database setup scripts into test/resources/db/migration/.

For your integration test setup you can also do one or combination of following options:

  1. Use for integration testing a maven profile and add in this setup a special flyway-maven-plugin or gradle setup that add the special folder test/resources/integration/migration/ for script locations.
  2. Use in test the identically folder test/resources/db/migration/ and use special versions such as V999.0.x__ or simular. In this case flyway will always fill all detected scripts in your database.
  3. If you have spring 4.x project you also can use spring-test with SqlScriptsTestExecutionListner. Here you can use specific load function for test case.
  4. use flyway-test-extensions

Tip for database integration tests:

  • avoid database reset for single tests. Test will be faster and robust.
  • each test data setup should be self contained and should not be disturbed by a other test run.
  • If you need upgrade from existing delivered instance also add migration test for filled database in your test setup. => Test your migration scripts.
like image 43
Florian E. Avatar answered Sep 17 '22 10:09

Florian E.