多测试类运行时Testcontainers @ServiceConnection抽象集成测试问题
使用Testcontainers + @ServiceConnection集成测试的多类执行问题
问题场景
多个测试类继承同一个抽象集成测试类AbstractIntegrationTest,单独运行每个测试类均正常,但批量运行所有测试类时,仅第一个测试类执行成功,后续全部失败。
抽象类代码
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @AutoConfigureMockMvc @Testcontainers @ActiveProfiles("test") public abstract class AbstractIntegrationTest { @Autowired protected MockMvc client; @Autowired ObjectMapper mapper; @Container @ServiceConnection static PostgreSQLContainer<?> postgresDB = new PostgreSQLContainer<>("postgres:16.3"); }
错误现象
错误日志显示容器启动后,后续测试尝试连接的端口与容器实际端口不匹配(错误端口比实际端口小1),同时伴随Hikari连接池连接失效警告,最终连接被拒绝:
2024-05-21T22:53:27.678+02:00 INFO 369738 --- [ Test worker] tc.postgres:16.3 : Creating container for image: postgres:16.3 2024-05-21T22:53:27.703+02:00 INFO 369738 --- [ Test worker] tc.postgres:16.3 : Container postgres:16.3 is starting: 2214d73f09c3600beeadbd6a9031473e2dae9526c987991371a9f4fd22af5c59 2024-05-21T22:53:28.932+02:00 INFO 369738 --- [ Test worker] tc.postgres:16.3 : Container postgres:16.3 started in PT1.253347718S 2024-05-21T22:53:28.932+02:00 INFO 369738 --- [ Test worker] tc.postgres:16.3 : Container is started (JDBC URL: jdbc:postgresql://localhost:32779/test?loggerLevel=OFF) 2024-05-21T22:53:29.044+02:00 WARN 369738 --- [ Test worker] com.zaxxer.hikari.pool.PoolBase : HikariPool-1 - Failed to validate connection org.postgresql.jdbc.PgConnection@5c2ae7d7 (This connection has been closed.). Possibly consider using a shorter maxLifetime value. 2024-05-21T22:53:29.045+02:00 WARN 369738 --- [ Test worker] com.zaxxer.hikari.pool.PoolBase : HikariPool-1 - Failed to validate connection org.postgresql.jdbc.PgConnection@7e122a87 (This connection has been closed.). Possibly consider using a shorter maxLifetime value. ... 2024-05-21T22:53:59.046+02:00 ERROR 369738 --- [ Test worker] o.h.engine.jdbc.spi.SqlExceptionHelper : Connection to localhost:32778 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
问题根源推测:批量测试时容器被重新初始化,但@ServiceConnection未同步更新Spring的数据源配置,导致后续测试仍使用旧端口连接;同时Hikari连接池持有失效连接未及时清理。
已尝试的无效操作
为容器添加withReuse(true)配置,但未解决问题:
@Container @ServiceConnection static PostgreSQLContainer<?> postgresDB = new PostgreSQLContainer<>("postgres:16.3").withReuse(true);
解决方案(保留@ServiceConnection)
1. 启用Testcontainers全局复用配置
在用户主目录创建/编辑~/.testcontainers.properties,添加:
testcontainers.reuse.enable=true
仅代码中设置withReuse(true)无效,必须通过全局配置开启复用功能,这样容器会在测试间复用,避免重复创建导致端口变化。
2. 配置容器固定标识
修改抽象类中的容器定义,添加固定名称确保复用匹配:
@Container @ServiceConnection static PostgreSQLContainer<?> postgresDB = new PostgreSQLContainer<>("postgres:16.3") .withReuse(true) .withName("test-integration-postgres"); // 固定名称,保证复用容器的一致性
3. 优化Hikari连接池配置
在application-test.yml中调整连接池参数,确保旧连接被及时清理:
spring: datasource: hikari: max-lifetime: 60000 # 1分钟,缩短连接生命周期,快速淘汰失效连接 connection-test-query: SELECT 1 # 每次获取连接时验证有效性
4. 可选:统一Spring测试上下文
确保所有测试类的配置一致,避免因上下文重新加载导致旧配置残留。可在抽象类添加:
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
减少测试上下文的创建次数,提升效率的同时避免配置不一致问题。
内容的提问来源于stack exchange,提问作者Roger Frauca Cordoba
相关产品推荐
相关产品推荐

