flyway / flyway-test-extensions

Apache License 2.0
129 stars 35 forks source link

Add functionality to reset DB state before each test in a test class (without explicitly adding @FlywayTest to every test) #31

Closed andersthorbeck closed 7 years ago

andersthorbeck commented 7 years ago

It is a common use case to reset the DB-state to a known base-state before each test, so they can all be run independently of each other, and not pass/break depending on which tests were run previously. I cannot find a simple way to perform this use case with this library.

I initially expected that annotating the test class with @FlywayTest would be the same as adding the annotation to every test, i.e. would reset the DB-state (maybe by performing a clean & migrate) before every single test in that test class. However, per the documentation of org.flywaydb.test.junit.FlywayTestExecutionListener

If the annotation FlywayTest used on class level a clean , init , migrate cycle is done during class load.

it seems that adding the annotation at the class level will only perform these actions before the first test, not before every test.

I feel that having to add this annotation to every test is unnecessary boilerplate I want to avoid. One solution is as explained in https://stackoverflow.com/a/41929329/854151 by explicitly autowiring-in the Flyway instance and calling clean() and migrate() on it in a @Before-method. But, since the @FlywayTest annotation already exists and is intended to do pretty much what we want, it would be better to change the behaviour of this annotation instead.

Possible solutions using the @FlywayTest annotation:

FlorianGWE commented 7 years ago

Hi Andreas,

I will prefer your second choice.

I will also plan to integrate this in the next Release.

Florian

Am 3. Juli 2017 15:29:24 MESZ schrieb "Anders R. Thorbeck" notifications@github.com:

It is a common use case to reset the DB-state to a known base-state before each test, so they can all be run independently of each other, and not pass/break depending on which tests were run previously. I cannot find a simple way to perform this use case with this library.

I initially expected that annotating the test class with @FlywayTest would be the same as adding the annotation to every test, i.e. would reset the DB-state (maybe by performing a clean & migrate) before every single test in that test class. However, per the documentation of org.flywaydb.test.junit.FlywayTestExecutionListener

If the annotation FlywayTest used on class level a clean , init , migrate cycle is done during class load.

it seems that adding the annotation at the class level will only perform these actions before the first test, not before every test.

I feel that having to add this annotation to every test is unnecessary boilerplate I want to avoid. One solution is as explained in https://stackoverflow.com/a/41929329/854151 by explicitly autowiring-in the Flyway instance and calling clean() and migrate() on it in a @Before-method. But, since the @FlywayTest annotation already exists and is intended to do pretty much what we want, it would be better to change the behaviour of this annotation instead.

Possible solutions using the @FlywayTest annotation:

  • Changing the behaviour of @FlywayTest when used on class level. This might not be preferable, as it will change the behaviour of existing code.
  • Adding an option/element to @FlywayTest allowing us to specify whether we want the behaviour to trigger only once for the class, or once for each test. For comparison, see the 4 different available options of the classMode element of annotation @org.springframework.test.annotation.DirtiesContext: BEFORE_CLASS, BEFORE_EACH_TEST_METHOD, AFTER_EACH_TEST_METHOD, AFTER_CLASS. This strikes me as the best option.
  • Make the @FlywayTest work together with @Before or @After annotations, when both annotations are present on the same method. This approach would work, but is a little inelegant if you have to create a method that would otherwise be empty, just so you can apply to annotations to it. See: https://stackoverflow.com/questions/18390817/junit-testing-flyway-can-you-combine-before-and-flyway-annotations

-- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/flyway/flyway-test-extensions/issues/31

FlorianGWE commented 7 years ago

Hallo Anders,

I implement a first solution to use @FlywayTest annotation together with @Before annotation.

You will find a example in https://github.com/flyway/flyway-test-extensions/blob/master/flyway-test-extensions/flyway-spring-test/src/test/java/org/flywaydb/test/sample/junit/BaseJunitBeforeTest.java. Will this help you ?

Florian

andersthorbeck commented 7 years ago

Hi Florian,

Apologies for my late reply. I have upgraded my flyway-test-extensions dependency to the new 4.2.0 release, and the new behaviour of the @FlywayTest annotation seems to work excellently, and solves my original issue.

Many thanks! Anders