Restore database state after integration test using Docker?

We are using PostgreSQL along with EAR deployed to JBoss. During the build process we have a development database dump that is used then in integration test: special artifact is deployed and tests communicate with the app using http client.

Currently, the database state changes during tests run, so we have no way but to put additional content for each test that modifies it, so no tests would depend each other. It takes really lots of time and patience as such test become even dependent on the order of records.

  • Apache Flink 1.2 - Client is not connected to any Elasticsearch nodes
  • Heroku run Docker image with port parameter
  • How to install Cloud Foundry CLI on Ubuntu
  • Docker Maven plugin: how to specify shm size when running a container
  • Docker image TCP buffer size
  • Docker error while PULL - Error downloading dependent layers
  • Is there a way to make a snapshot of DB so that to restore it after each test run with a reasonable amount of resources? Could Docker help? Or any other way around?

    H2 is not the way, because we use some PostgreSQL-specific features. Tests may span multiple transactions, so I guess rollback would not help either.

  • See full command of running/stopped container in Docker
  • Docker can't find OpenJDK
  • Problems with multiple intances of an back-end java application with a Firebase Listener
  • Docker port mapping not working, “connection refused”
  • X11 fowarding from Windows into Docker
  • docker run container happens error when mapped the container's port with machine
  • 3 Solutions collect form web for “Restore database state after integration test using Docker?”

    One straightforward way with Docker is to have your database snapshot as a volume you reset and then mount into the beginning of your test run.

    You can massage this data prior to your tests running (either have a tar of your entire starting database config or something else), then launch your PostgreSQL test database, with the test data mounted as a volume and your PostgreSQL pointing to this, for each test.

    One option is to re-seed the data after each integration test is completed. Spring offers such feature via SqlScriptsTestExecutionListener and @Sql annotation. I know you mentioned EAR and JBoss, so if Spring is not being used, I believe Arquillian might offer something similar.

    In case re-seeding the DB becomes an expensive operation due to the amount of data used for integration testing, another option would be to use a Docker image with the DB and seeded data already included. You would need to start the DB with data container before each integration test is executed and stopped after it has completed, in other words, you would need to manage the container life-cycle for the duration of the integration tests. I blogged about how to accomplish this so a few months ago: Integration Testing using Spring Boot, Postgres and Docker, again, using Spring Boot, but the ideas would be valid to use with another framework. It covers creating the Docker images with imported data, generating the JPA entities from existing schema, adding support for Integration Tests to start / stop container before and after each test is executed, and it could be easily extended to start more than one container per test or to execute them concurrently since the Docker container is mapped to a host random port.

    At this point it’s a compromise, starting each test from a know state (IMHO, the right approach) at the expense of either re-seed the data or start / stop containers for each individual test or run the tests in certain order and just re-seed the data before the test suite is execute.

    You can do this by cloning the initial database and dropping the newly created test database after the test. When using the original database as a “TEMPLATE” this will probably only take milliseconds.

    // Create "initial_database" before all tests are run and load fixtures etc.

    CREATE DATABASE some_test_database_name TEMPLATE "initial_database";

    DROP DATABASE some_test_database_name;

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.