一些测试运行后测试容器失去连接
Posted
技术标签:
【中文标题】一些测试运行后测试容器失去连接【英文标题】:Testcontainers loss of connection after some tests running 【发布时间】:2021-10-10 01:54:42 【问题描述】:我在我的 oss 软件中使用了 testcontainer,但我认为我的配置或 docker/testcontainer 运行时存在问题...
我有一些测试,当它们分开运行时,一切正常,但是当我尝试运行所有测试时,由于应用程序尝试与容器连接时出现问题,最后一次失败..
调试问题我发现容器在一个端口启动,但应用程序正在尝试在另一个端口连接,大部分都是在上次运行的测试类中使用
所有测试正在运行:
tests failing
其中一个失败的测试向我显示了这个日志:
log of failed test
当 UserControllerTest
启动的类使用另一个端口时,容器启动,如下所示:
docker on windows showing the container port
我的测试配置是基于一个抽象类(见下文),就像上面所说的,如果单独运行显示错误的类,一切正常。
@Testcontainers
@ActiveProfiles("test")
@ExtendWith(SpringExtension::class)
@TestMethodOrder(value = OrderAnnotation::class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
abstract class AbstractTest
companion object
@Container
private val redisContainer = GenericContainer<Nothing>("redis:6-alpine")
.apply
withExposedPorts(6379)
withCreateContainerCmdModifier cmd -> cmd.withName("wb-test-cache")
@Container
private val postgresContainer = PostgreSQLContainer<Nothing>("postgres:13-alpine")
.apply
withExposedPorts(5432)
withUsername("sa_webbudget")
withPassword("sa_webbudget")
withDatabaseName("webbudget")
withCreateContainerCmdModifier cmd -> cmd.withName("wb-test-database")
@JvmStatic
@DynamicPropertySource
fun dynamicPropertiesRegister(registry: DynamicPropertyRegistry)
registry.add("spring.datasource.url", postgresContainer::getJdbcUrl)
registry.add("spring.redis.host", redisContainer::getHost)
registry.add("spring.redis.port", redisContainer::getFirstMappedPort)
有人见过这样的事情知道如何解决吗?
【问题讨论】:
【参考方案1】:您想启动容器以供重用。把它放到方法链中:
.withReuse(true);
【讨论】:
这不是关于容器的重用,我希望每个测试类运行时都有一个新容器。问题是:在最后一个测试类中,容器端口没有正确设置,应用程序没有启动,因为spring无法连接数据库或redis【参考方案2】:根据文档:
声明为静态字段的容器将在测试方法之间共享。它们只会在任何测试方法执行之前启动一次,并在最后一个测试方法执行后停止。声明为实例字段的容器将为每个测试方法启动和停止。
所以也许你的容器会为每次测试重新启动并获得新的端口号?
见:https://www.testcontainers.org/test_framework_integration/junit_5/
我们运行与您想要完成的设置类似的设置,但在抽象类中使用@ContextConfiguration( initializers = [
,并在其中配置每个容器并添加到共享ConfigurableApplicationContext
的初始化程序列表。但是,如果您可以仅使用注释使其工作,您的方法似乎要简单得多。
【讨论】:
【参考方案3】:经过一番研究,我发现了问题所在:上下文。
当 spring 运行第一个 mvc 控制器测试时,它会为所有控制器启动一个 tomcat 实例,这意味着当 testcontainers 为数据库重新创建 docker 实例时(在新控制器开始测试之后)属性(端口、URL .. ) 未更新,因为 spring 将重用当前的 tomcat 实例(来自上一次 mvc 测试)
解决方案:将每个测试类的上下文标记为脏,这将使 spring 在每次新测试类启动时重新创建上下文,这将触发 dynamicPropertiesRegister
正确更新属性。
我只需要将此注释 @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
添加到我的 AbstractTest
【讨论】:
以上是关于一些测试运行后测试容器失去连接的主要内容,如果未能解决你的问题,请参考以下文章
Docker Pytest容器在完成测试过程后仍处于启动状态