参数化testcontainer图像标记与Junit5



在Testcontainers文档中,有一个使用@ParameterizedTest参数化docker映像的示例。

这是一个junit4的例子

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);
}
}

在junit5中我找不到类似的方法,基本上:

  • 对于类
  • 中的所有@ParameterizedTest方法,容器只启动一次

Ofc,有很多if/else,玩beforeEach, TestInfo,…是可能的,但我觉得有些不对劲,我确信下面的问题可能应该用junit5

来回答

如何使用参数化测试对多个数据库版本进行测试

所以,似乎不可能等同于junit5,这与上面Eddù提到的这个打开的问题https://github.com/junit-team/junit5/issues/878#issuecomment-546459081有关

在Michael Simons的大力帮助下,我可以设法做一些有效的事情

基类:

@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;
}
}

和实际的测试类

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

几个有用的链接

  • https://foojay.io/today/faster-integration-tests-with-reusable-testcontainers/
  • https://github.com/michael-simons/neo4j-migrations/blob/main/neo4j-migrations-core/src/test/java/ac/simons/neo4j/migrations/core/CatalogBasedMigrationIT.java
  • https://github.com/michael-simons/neo4j-migrations/blob/main/neo4j-migrations-core/src/test/java/ac/simons/neo4j/migrations/core/TestBase.java L49

开发测试引擎(基于Junit5)支持参数化类测试。(我是作者)

https://github.com/devopology/test-engine

你的例子…

package test.neo4j;
import org.devopology.test.engine.api.AfterAll;
import org.devopology.test.engine.api.BeforeAll;
import org.devopology.test.engine.api.Parameter;
import org.devopology.test.engine.api.Test;
import org.testcontainers.containers.Neo4jContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import java.util.ArrayList;
import java.util.Collection;
public class Neo4jTest {
@Parameter
public String dockerImageName;
@Parameter.Supplier
public static Collection<String> dockerImageNames() {
Collection<String> dockerImageNames = new ArrayList<>();
dockerImageNames.add("neo4j:4.4.14-enterprise");
dockerImageNames.add("neo4j:5.2.0-enterprise");
return dockerImageNames;
}
private Neo4jContainer<?> neo4jContainer;
@BeforeAll
public void beforeAll() {
neo4jContainer = new Neo4jContainer<>(dockerImageName)
.waitingFor(Wait.forLogMessage(".*Started..*", 1))
.withEnv("NEO4J_ACCEPT_LICENSE_AGREEMENT", "yes")
.withEnv(heapSizeSetting(dockerImageName), "256M")
.withLogConsumer(outputFrame -> System.out.print(outputFrame.getUtf8String()))
.withoutAuthentication();
neo4jContainer.start();
}
@Test
public void test1() {
System.out.println("test1 : dockerImageName = [" + dockerImageName + "]");
// do something here
}
@Test
public void test2() {
System.out.println("test2 : dockerImageName = [" + dockerImageName + "]");
// do something here
}
@AfterAll
public void afterAll() {
if (neo4jContainer != null) {
try {
neo4jContainer.close();
} catch (Throwable t) {
// DO NOTHING
}
neo4jContainer = null;
}
}
protected static String heapSizeSetting(String dockerImageName) {
return dockerImageName.contains("4.4")
? "NEO4J_dbms_memory_heap_max__size" : "NEO4J_server_memory_heap_max__size";
}
}

最新更新