3

I am using Micronaut 2.4.0 and using testContainers for SQL Server Integration testing.

Here is my gradle.build

    testImplementation("org.testcontainers:testcontainers")
    testImplementation("org.testcontainers:junit-jupiter")
    testImplementation("org.testcontainers:mssqlserver")

Here is application.yml for test

    url: jdbc:tc:sqlserver://localhost;databaseName=test-db
    username: sa
    password: sa
    driverClassName: org.testcontainers.jdbc.ContainerDatabaseDriver

These are the only changes and micronaut handles creating and starting of testcontainers.

Problem

For each test classes, it creates new container. Most of the time test takes is in container creation.

Is there a way we can re-use the container ? (clearing the DB might still be okay)

Akshay
  • 3,558
  • 4
  • 43
  • 77
  • I'm not sure if the Testcontainers re-use feature works with the JDBC support. With a manual container definition, it will definitely work (as seen in this [similar question](https://stackoverflow.com/questions/62425598/how-to-reuse-testcontainers-between-multiple-springboottests/62443261#62443261)). You can find a detailed example also [here](https://rieckpil.de/reuse-containers-with-testcontainers-for-fast-integration-tests/) (using Spring Boot, but the setup is similar). – rieckpil Mar 18 '21 at 06:52
  • It is easy in spring botth, same does not work in micronaut. application.yml has the connection string. Need some way to initialize testcontainers before app starts – Akshay Mar 21 '21 at 21:16
  • Do you use annotation `@Container` ? If yes you shouldn't. Please see https://stackoverflow.com/a/62443261/696714 – TOUDIdel Oct 18 '21 at 12:24

3 Answers3

3

Late reply but, in case someone stumbles on this.

Try adding TC_REUSABLE=true into the jdbc URL

i.e: jdbc:tc:sqlserver://localhost;databaseName=test-db/TC_INITSCRIPT=db/customer_database_schema.sql&TC_REUSABLE=true

Peter S
  • 41
  • 4
  • This works. My previous config "testcontainers.reuse.enable: true" didn't work, it's probably a setting for Spring Boot not Micronaut – X.Y. Dec 28 '21 at 05:58
0

The other answer could be right.

I got it working with TC_DAEMON=true parameter in jdbc URL

So, it becomes

url: jdbc:tc:sqlserver://localhost;databaseName=mydb?TC_DAEMON=true

Edit

Eventually I moved away from test containers and now starting with docker manually

Akshay
  • 3,558
  • 4
  • 43
  • 77
0

Actually better approach will be creating singleton class with reusable container and applying it to every test which uses database

@Testcontainers
public class PostgresContainer implements TestPropertyProvider {

    private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER;

    static {
        POSTGRE_SQL_CONTAINER = new PostgreSQLContainer(DockerImageName.parse("postgres:latest"))
                .withDatabaseName("test")
                .withPassword("test")
                .withUsername("test");
        POSTGRE_SQL_CONTAINER.start();
    }

    @Override
    public Map<String, String> getProperties() {
        return Map.of(
                "datasource.default.jdbc-url", POSTGRE_SQL_CONTAINER.getJdbcUrl(),
                "datasource.default.username", POSTGRE_SQL_CONTAINER.getUsername(),
                "datasource.default.password", POSTGRE_SQL_CONTAINER.getPassword()
        );
    }
}

@MicronautTest
class BaseDatabaseTest extends PostgresContainer {...}

Note that with Singleton pattern, container will be created only once and be reused in every single test class

szachMati
  • 196
  • 2
  • 12