Search code examples
jpaeclipselinkflywayjboss-arquillian

How to reset the database for Arquillian UI tests


I have a default Java EE 7 application with JPA/Eclipselink. I want to write some UI tests with Arquillian Drone/Graphene.

My testsuite is "working". I can click through the application and make some asserts.

But: I want to create multiple tests. Every test class should reset the database, to make sure, that the conditions are always the same.

I'm using flyway to reset my database.

@Before
public void setup() {
 Flyway flyway = new Flyway();
 flyway.setDataSource(...);
 flyway.clean();
 flyway.init();
 flyway.migrate();
}

The reset is working. And the first execution of the test also (at this situation, nothing is in any cache). When I try to execute the test again, the database is inconsistent with strange JPA errors. First I thought ok: Reset the cache

getEntityManager().getEntityManagerFactory().getCache().evictAll();

Is not enough. Same problems. Next idea was to destroy the sessions (Some JPA data could be saved in old sessions). I haven't found a good way to destroy all sessions. I made a workaround, but this doesn't work also.

I think I have a default problem, but I can not found any solutions for this problem.

I also tried dbunit and the arquillian-persistence-extension. But it is like flyway, just another way.

In theory the problem is, that the database has been reset manually over SQL and Java/JPA/EclipseLink/The Sessions/deployed applaction have no idea about the changed data. How can I reset everything (all Caches?)?

I also thought about "redeploy before start testclass". But this is a little bit to much (takes more time and is no fine solution)?

One more information: I'm also doing normal arquillian-tests (without UI/Selenium), here is my flyway database reset working.

Thanks for help :).


Solution

  • You didn't say what errors you really got, you just said:

    When I try to execute the test again, the database is inconsistent with strange JPA errors (...)

    It is hard to believe that your problem lies in JPA cache. I think that your problem has totally different source.

    Your approach to cleaning the database has a fundamental flaw. Code that you've presented: should be run only once, before all tests. Because Flyway is meant to prepare the database structure, not to setup it into known state.
    So conceptually DbUnit & Arquillian Persistence Extension and Flyway do two really different things. They are not a replacement for each other.

    So your code that uses flyway:

    @Before
    public void setup() {
     ...
      flyway.clean();
      flyway.init();
      flyway.migrate();
    }
    

    is wrong, because it should be run only once before all tests. To do that you can use some container features:

    1. If using EJB Container, then @Singleton + @Startup + @PostConstruct combination could be used to launch flyway tool.
    2. If using Spring Container, then init-method="migrate" would do the trick.
    3. Or use maven and its pre-integration-test phase to launch flyway tool.

    By the way: to avoid maintenance effort associated with DbUnit's xml datasets, personally I would recommend DbSetup tool. Nice and simple solution.

    Edit

    Besides the fact, that changing the DB structure during tests isn't a good practice - your problem may also be caused that both Flyway and JPA are using different datasources (even pointing to the same DB). You should double check that you're not creating DataSource on your own - just inject for the Flyway the same one that PersistenceUnit is using.