javajunit5testcontainerstestcontainers-junit5

Parameterized testcontainer image tag with Junit5


In the Testcontainers documentation, there is an example for having the docker image to be parameterized with @ParameterizedTest.

This was a junit4 example.

https://github.com/testcontainers/testcontainers-java/blob/main/core/src/test/java/org/testcontainers/junit/ParameterizedDockerfileContainerTest.java

@RunWith(Parameterized.class)
public class ParameterizedDockerfileContainerTest {

    private final String expectedVersion;

    @Rule
    public GenericContainer container;

    public ParameterizedDockerfileContainerTest(String baseImage, String expectedVersion) {
        container =
            new GenericContainer(
                new ImageFromDockerfile()
                    .withDockerfileFromBuilder(builder -> {
                        builder
                            .from(baseImage)
                            // Could potentially customise the image here, e.g. adding files, running
                            //  commands, etc.
                            .build();
                    })
            )
                .withCommand("top");
        this.expectedVersion = expectedVersion;
    }

    @Parameterized.Parameters(name = "{0}")
    public static Object[][] data() {
        return new Object[][] { //
            { "alpine:3.12", "3.12" },
            { "alpine:3.13", "3.13" },
            { "alpine:3.14", "3.14" },
            { "alpine:3.15", "3.15" },
            { "alpine:3.16", "3.16" },
        };
    }

    @Test
    public void simpleTest() throws Exception {
        final String release = container.execInContainer("cat", "/etc/alpine-release").getStdout();

        assertThat(release).as("/etc/alpine-release starts with " + expectedVersion).startsWith(expectedVersion);
    }
}

I couldn't find a way to do something similar with junit5, basically :

Ofc, with a lot of if/else, playing with beforeEach, TestInfo, ... is possible but I feel like something is wrong and I'm sure the following question has probably should be answered with junit5

How to use parameterized tests for testing with multiple database versions


Solution

  • So, it seems the equivalent to junit5 is not possible, related to this opened issue https://github.com/junit-team/junit5/issues/878#issuecomment-546459081 as mentioned by Eddù above

    With the great help of Michael Simons, I could manage to do something that works

    Base class :

    @Testcontainers(disabledWithoutDocker = true)
    @TestInstance(TestInstance.Lifecycle.PER_CLASS)
    public abstract class MultipleNeo4jVersionsTest {
    
        protected static String HEAP_SIZE = "256M";
    
        public static Stream<String> neo4jVersions() {
            return Stream.of("4.4.14", "5.2.0");
        }
    
        protected static String heapSizeSetting(Neo4jVersion version) {
            return version.equals(Neo4jVersion.V4_4)
                    ? "NEO4J_dbms_memory_heap_max__size"
                    : "NEO4J_server_memory_heap_max__size"
                    ;
        }
    
        protected Neo4jContainer<?> getNeo4j(String version) {
            var imageName = String.format("neo4j:%s-enterprise", version);
            Neo4jVersion neo4jVersion = Neo4jVersion.of(version);
            Neo4jContainer<?> container = new Neo4jContainer<>(imageName)
                    .withoutAuthentication()
                    .withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes")
                    .withEnv(heapSizeSetting(neo4jVersion), HEAP_SIZE)
                    .withReuse(true);
            container.start();
    
            return container;
        }
    }
    

    And the actual test class

    @ParameterizedTest
        @MethodSource("neo4jVersions")
        void loading_config(String version) throws Exception {
            Neo4jContainer<?> neo4j = getNeo4j(version);
            // do something here
    
        }
    

    Couple of useful links