Is there a way to disable Testcontainers depending on Spring profile?

Viewed 2773

I am using Spring Boot and running tests in Testcontainers.

Sometimes (when developing) I would like to run tests not against Testcontainers, but against already running containers.

Is there a way to disable Testcontainers depending on Spring profiles, environment variables, etc.?

Right now I am commenting the container injection code and regularly check them in like that.

3 Answers

Yes, it can be done using profiles.

One possible solution would be (the idea is to play around with static keyword and it assumes using .withLocalCompose(true)):

@Configuration
@Profile("test")
public class TestDockerConfig {
    // initialize your containers in static fields/static block
}

And use the test profile when you need it. Even if you import that configuration in all tests, it should only be loaded for "test" ones.

The idea is to have docker environment provided to test suite and use property profiles. It can either:

  • be provided by local docker engine ("dev") where you start containers yourself with proper dev URLs specified in application-dev.properties
  • or provided via TestContainers, with test URLs in application-test.properties

Since starting up containers takes time you want to do that only once in a static way and it will be loaded before all of your classes.

Hope that helps.

One way to get containers in your test is just to use the JDBC URL, per the docs. This allows you to easily switch between e.g. Testcontainers and localhost based on a profile:

application-integration.yml

spring.datasource.url: jdbc:tc:postgresql:12-alpine:///mydatabase

application-dev.yml

spring.datasource.url: jdbc:postgresql://localhost:5432/mydatabase

As the documentation notes:

  • TC needs to be on your application's classpath at runtime for this to work
  • For Spring Boot (Before version 2.3.0) you need to specify the driver manually spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver

As recommended by Sergei here https://github.com/testcontainers/testcontainers-java/issues/2833#event-3405411419

this is the solution:

public class FixedHostPortGenericDisableableContainer<T extends FixedHostPortGenericDisableableContainer<T>> extends FixedHostPortGenericContainer<T> {

    private boolean isActive;

    public FixedHostPortGenericDisableableContainer(@NotNull String dockerImageName) {
        super(dockerImageName);
    }

    @Override
    public void start() {
        if (isActive) {
            super.start();
        }
    }

    public FixedHostPortGenericDisableableContainer isActive(boolean isActive) {
        this.isActive = isActive;
        return this;
    }
}

Usage

// set this environment variable to true to disable test containers
    public static final String ENV_DISABLE_TEST_CONTAIENRS = "DISABLE_TEST_CONTAIENRS";

    @Container
    private static GenericContainer dynamoDb =
            new FixedHostPortGenericDisableableContainer("amazon/dynamodb-local:1.11.477")
                    .isActive(StringUtils.isBlank(System.getenv(ENV_DISABLE_TEST_CONTAIENRS)))
                    .withFixedExposedPort(8001, 8000)
                    .withStartupAttempts(100);
Related