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.

  • Docker Alpine nginx 403 Forbidden error for swagger-ui-builder
  • Access application deployed in windows docker container from other machine
  • Docker daemon config file on boot2docker / docker-machine / Docker Toolbox
  • Docker expose link to host machine
  • Pycharm Docker port bindings
  • Docker login problems
  • 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.

  • Kubernetes - ReplicationController and Persistent Disks
  • Citrus-Framework: How to start/stop docker container in doFinally()?
  • Sharing exclusive files to docker instances from host
  • Docker containers having trouble exposing ports to host on Mac
  • Running multiple instances of an image with docker-compose fails
  • Docker centos:6 mounting webdav client with ec2 loadbalancer webdav server
  • 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.