4

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.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Skip
  • 6,240
  • 11
  • 67
  • 117

3 Answers3

2

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.

Vitaly Chura
  • 704
  • 8
  • 13
2

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);
Skip
  • 6,240
  • 11
  • 67
  • 117
1

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
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • That would only work for the `jdbc`, right? One of my containers contains an LDAP server. Also in one environment - I dont have docker-engine available. So Exceptions are flighing, if the containers are even present and active. So in order to solve my problems - the containers should not be injected. Even the check for the docker-engine should not happen. – Skip Jun 03 '20 at 19:10
  • @Skip yes, only for containers that can be wired via a "magic URL". And I don't know whether it would still try to use Docker at all in the `dev` profile - my local database is *also* provided via Docker, so it'll bin out either way! – jonrsharpe Jun 03 '20 at 19:15