embedded-database-spring-test

repository·master·Indexed 19 days ago

https://github.com/zonkyio/embedded-database-spring-test

A library for Spring-powered integration testing that provides managed, isolated, and high-performance embedded databases including PostgreSQL, MySQL, MSSQL, H2, HSQLDB, and Derby. It utilizes Testcontainers or Zonky providers and features the @AutoConfigureEmbeddedDatabase annotation to automatically inject DataSources into the Spring context. The library supports database refreshing for test isolation, integration with @DataJpaTest and @JdbcTest, and automated migrations via @FlywayTest.

Tokens
6.9K
Snippets
27
Records
32
Agent score
17%

What's inside embedded-database-spring-test

  1. Refresh the database to ensure test isolation

    master

    To prevent data leakage between tests, use the refresh attribute in @AutoConfigureEmbeddedDatabase. This resets the database to its initial state (including reverting committed changes) using fast template database copying rather than standard transaction rollbacks.

    Available refresh modes:

    • AFTER_CLASS: Refreshes the database after each test class completes.
    • AFTER_EACH_TEST_METHOD: Refreshes the database after every individual test method.

    Note: If no refresh mode is specified, all tests in the project will share the same database instance.

    @ExtendWith(SpringExtension.class)
    @AutoConfigureEmbeddedDatabase(refresh = AFTER_EACH_TEST_METHOD)
    public class EmptyDatabaseIntegrationTest {
    
        @Test
        void testMethod1() {
            // fresh database
        }
    
        @Test
        void testMethod2() {
            // fresh database
        }
    }
  2. Compare Database Providers

    master

    The library supports multiple database providers, allowing you to choose between flexibility (Docker) and speed (Native providers like Zonky). You can configure a provider globally via the zonky.test.database.provider property or per-class using the @AutoConfigureEmbeddedDatabase(provider = ...) annotation.

    FeatureDockerZonkyOpenTableYandex
    Startup TimeSlightly slowerFastFastSlow
    PerformanceSlightly slowerNativeNativeNative
    Supported DBsPostgreSQL, MSSQL, MySQL, MariaDBPostgreSQLPostgreSQLPostgreSQL
    Configurable VersionYes (runtime)Yes (compile time)NoYes (runtime)
    Alpine SupportYesYesNoNo
  3. Understand background bootstrapping mode

    master

    By default, the library uses background bootstrapping for DataSource initialization and Flyway/Liquibase migrations.

    Instead of waiting for migrations to finish, the library immediately returns a DataSource proxy. The first actual call to a data source method will block until bootstrapping is complete. To maximize the benefits of this mode, avoid calling the data source inside the @PostConstruct or init methods of related beans.

  4. Configure PostgreSQL for embedded testing

    master

    To use PostgreSQL as your embedded database, add the PostgreSQL JDBC driver to your Maven dependencies. The PostgreSQL provider supports all available features, including template databases and database prefetching, for maximum performance.

    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.7.10</version>
    </dependency>
  5. Build the project from source

    master

    The project uses Gradle.

    Prerequisites:

    • Git
    • JDK 8 or later (ensure JAVA_HOME points to the JDK folder).

    Steps:

    1. Clone the repository: git clone git@github.com:zonkyio/embedded-database-spring-test.git
    2. Run the build: ./gradlew build
    git clone git@github.com:zonkyio/embedded-database-spring-test.git
    ./gradlew build
  6. Configure Flyway for optimized migrations

    master

    Flyway is highly optimized in this library. Adding the flyway-core dependency enables support. For enhanced testing, you can add the flyway-spring-test extension to use the @FlywayTest annotation.

    Processing of @FlywayTest is internally optimized to use database prefetching and template databases (where supported) to speed up applying new migrations after a database clean.

    <!-- Core Flyway -->
    <dependency>
        <groupId>org.flywaydb</groupId>
        <artifactId>flyway-core</artifactId>
        <version>11.20.3</version>
    </dependency>
    
    <!-- Optional: Flyway Test Extensions for @FlywayTest -->
    <dependency>
        <groupId>org.flywaydb.flyway-test-extensions</groupId>
        <artifactId>flyway-spring-test</artifactId>
        <version>10.0.0</version>
        <scope>test</scope>
    </dependency>
  7. Run tests in Docker or Alpine Linux

    master

    PostgreSQL requires the database process to run under a non-root user when running in Docker.

    Options:

    1. Use a non-root user: Configure your Dockerfile to create and switch to a non-root user.
    2. Use Privileged Mode: Since version 1.5.5, you can run the container with the --privileged flag to allow the unshare command to run the database in a separate namespace.
    3. GitLab Runner: If using the Docker executor in GitLab, set privileged = true in your [[runners.docker]] configuration.
    ```dockerfile
    # Standard Dockerfile example
    FROM openjdk:8-jdk
    RUN groupadd --system --gid 1000 test
    RUN useradd --system --gid test --uid 1000 --shell /bin/bash --create-home test
    USER test
    WORKDIR /home/test
    # Alpine Dockerfile example
    FROM openjdk:8-jdk-alpine
    RUN addgroup -S -g 1000 test
    RUN adduser -D -S -G test -u 1000 -s /bin/ash test
    USER test
    WORKDIR /home/test

    GitLab Runner configuration

    [[runners]] executor = "docker" [runners.docker] privileged = true

  8. Configure MySQL for embedded testing

    master

    To use MySQL, add the mysql-connector-java dependency.

    Performance Note: The MySQL provider only supports basic features required for embedded database operation. You may notice performance degradation because MySQL treats database and schema as synonymous, making database prefetching difficult, and it lacks support for fast binary backups required for template database emulation.

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.33</version>
    </dependency>
  9. Disable auto-configuration

    master

    The library automatically registers context customizers and test execution listeners. To disable this, exclude the embedded-database-spring-test-autoconfigure dependency from your Maven configuration.

    <dependency>
        <groupId>io.zonky.test</groupId>
        <artifactId>embedded-database-spring-test</artifactId>
        <version>2.8.0</version>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>io.zonky.test</groupId>
                <artifactId>embedded-database-spring-test-autoconfigure</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
  10. Configure Liquibase for embedded testing

    master

    To use Liquibase, add the liquibase-core dependency. Since Liquibase does not have a direct equivalent to @FlywayTest, it is recommended to use the library's refresh mode to refresh the embedded database during tests.

    <dependency>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-core</artifactId>
        <version>5.0.2</version>
    </dependency>
  11. Use the Docker Provider (Default)

    master

    The Docker provider is the default. It is ideal for testing database extensions or custom Docker images. Use @AutoConfigureEmbeddedDatabase without arguments to use it.

    Docker-specific configuration: Configure images and tmpfs settings using the zonky.test.database.<db-type>.docker group (e.g., postgres, mysql, mariadb, mssql).

    Customization via Bean: Implement PostgreSQLContainerCustomizer to customize the container (e.g., setting startup timeouts).

    @ExtendWith(SpringExtension.class)
    @AutoConfigureEmbeddedDatabase
    public class DefaultProviderIntegrationTest {
        // class body...
    }
    @Bean
    public PostgreSQLContainerCustomizer postgresContainerCustomizer() {
        return container -> container.withStartupTimeout(Duration.ofSeconds(60L));
    }
  12. Use the Yandex Provider (Deprecated)

    master

    The Yandex provider is deprecated and scheduled for removal. Use the Zonky provider instead.

    Setup:

    1. Add ru.yandex.qatools.embed:postgresql-embedded dependency.
    2. Use @AutoConfigureEmbeddedDatabase(provider = YANDEX).

    Configuration: Use zonky.test.database.postgres.yandex-provider.postgres-version to specify the EnterpriseDB PostgreSQL binary version.

    <dependency>
        <groupId>ru.yandex.qatools.embed</groupId>
        <artifactId>postgresql-embedded</artifactId>
        <version>2.10</version>
        <scope>test</scope>
    </dependency>
    zonky.test.database.postgres.yandex-provider.postgres-version=11.10-1