如何在与 quarkus 的集成测试期间重用容器?
How can I reuse containers during integration tests with quarkus?
我目前有一些 运行 很好的集成测试,但是我正在使用注释 @QuarkusTestResource 在启动 quarkus 之前通过 testcontainers 启动容器,并且我将我的属性调整为随机测试容器端口通过覆盖我的容器的启动方法 class 扩展 QuarkusTestResourceLifecycleManager。
为了优化一点,我想重新使用启动 kafka 的容器,因为启动它需要 6-8 秒,并将其重新用于我的几个集成测试。我没能这样做。由于 Quarkus 每次停止时都会管理生命周期,在每次测试 class 之间,它还会停止每个容器。我尝试将 singleton containers from testcontainers 与 Quarkus 测试资源混合使用,但它不起作用。这是我的一个集成测试开始的片段 class :
@QuarkusTest
@Tag(INTEGRATION_TEST)
@QuarkusTestResource(value = KafkaNode.class, restrictToAnnotatedClass = true, parallel = true)
class MyIntegrationTest { ... }
还有我的 KafkaNode class :
public class KafkaNode implements QuarkusTestResourceLifecycleManager {
static KafkaContainer kafka = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:6.2.1"))
.withNetworkAliases("kafkaNode")
.withNetwork(CommonNetwork.getInstance());
@Override
public Map<String, String> start() {
kafka.start();
return Collections.singletonMap("myapp.kafka.servers",
kafka.getBootstrapServers());
}
@Override
public void stop() {
kafka.close();
}
}
我愿意接受重用甚至返工我的测试的想法,以便我可以以另一种方式重用容器。
您可以通过 .withReuse(true)
为您的容器使用实验性可重用模式。
请注意,为了使其正常工作,您需要:
- 在
~/.testcontainers.properties
文件中设置 testcontainers.reuse.enable=true
属性
- NOT 调用
.close()
(以任何方式以编程方式停止容器)
一旦你相应地设置了所有内容,你的容器应该
- 不再stopped/garbage在测试结束时收集运行
- 在下一次测试中再次被拾起运行 - 避免新容器启动
请注意,所有 运行 时间修改(配置、数据、主题等)在下一次测试 运行 中仍将存在。您需要采取适当的措施来避免 non-deterministic 测试 - 例如为每个测试使用不同/随机的主题名称 运行.
另请注意,您需要在完成后手动 stop/delete 容器。 Testcontainers 将不再为您删除容器。
您还可以从 spring 阅读这篇描述如何做到这一点的文章以获取灵感:Reuse Containers With Testcontainers for Fast Integration Test
当使用多个 QuarkusTestProfile 时,测试上下文将被完全重置,因此即使是静态变量也不会被保留。
我还没有找到使用例如当使用不同的 QuarkusTestProfiles 时,一个测试中所有 QuarkusTest 的单个数据库。
即使看起来容器存在于测试 运行 边界,我也无法在后面的测试 运行 中引用它来确定映射端口等
我目前有一些 运行 很好的集成测试,但是我正在使用注释 @QuarkusTestResource 在启动 quarkus 之前通过 testcontainers 启动容器,并且我将我的属性调整为随机测试容器端口通过覆盖我的容器的启动方法 class 扩展 QuarkusTestResourceLifecycleManager。
为了优化一点,我想重新使用启动 kafka 的容器,因为启动它需要 6-8 秒,并将其重新用于我的几个集成测试。我没能这样做。由于 Quarkus 每次停止时都会管理生命周期,在每次测试 class 之间,它还会停止每个容器。我尝试将 singleton containers from testcontainers 与 Quarkus 测试资源混合使用,但它不起作用。这是我的一个集成测试开始的片段 class :
@QuarkusTest
@Tag(INTEGRATION_TEST)
@QuarkusTestResource(value = KafkaNode.class, restrictToAnnotatedClass = true, parallel = true)
class MyIntegrationTest { ... }
还有我的 KafkaNode class :
public class KafkaNode implements QuarkusTestResourceLifecycleManager {
static KafkaContainer kafka = new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:6.2.1"))
.withNetworkAliases("kafkaNode")
.withNetwork(CommonNetwork.getInstance());
@Override
public Map<String, String> start() {
kafka.start();
return Collections.singletonMap("myapp.kafka.servers",
kafka.getBootstrapServers());
}
@Override
public void stop() {
kafka.close();
}
}
我愿意接受重用甚至返工我的测试的想法,以便我可以以另一种方式重用容器。
您可以通过 .withReuse(true)
为您的容器使用实验性可重用模式。
请注意,为了使其正常工作,您需要:
- 在
~/.testcontainers.properties
文件中设置testcontainers.reuse.enable=true
属性 - NOT 调用
.close()
(以任何方式以编程方式停止容器)
一旦你相应地设置了所有内容,你的容器应该
- 不再stopped/garbage在测试结束时收集运行
- 在下一次测试中再次被拾起运行 - 避免新容器启动
请注意,所有 运行 时间修改(配置、数据、主题等)在下一次测试 运行 中仍将存在。您需要采取适当的措施来避免 non-deterministic 测试 - 例如为每个测试使用不同/随机的主题名称 运行.
另请注意,您需要在完成后手动 stop/delete 容器。 Testcontainers 将不再为您删除容器。
您还可以从 spring 阅读这篇描述如何做到这一点的文章以获取灵感:Reuse Containers With Testcontainers for Fast Integration Test
当使用多个 QuarkusTestProfile 时,测试上下文将被完全重置,因此即使是静态变量也不会被保留。 我还没有找到使用例如当使用不同的 QuarkusTestProfiles 时,一个测试中所有 QuarkusTest 的单个数据库。 即使看起来容器存在于测试 运行 边界,我也无法在后面的测试 运行 中引用它来确定映射端口等