我正在使用Postgres数据库后端处理一个 Boot 项目,其中JUnit5和Testcontainers用于涉及数据库访问的集成测试。
Testcontainers是通过如下修改JDBC URL来设置的:
spring:
datasource:
url: jdbc:tc:postgresql:9.6.8:///test
这个设置确实工作了好几个月,但现在我遇到了一个障碍。
到目前为止,已经有20个集成测试类,添加另一个类会导致测试失败,因为在我看来,这是一个超时错误。
当添加第21个测试类时,另一个测试(我们称之为RandomTest
)挂起几分钟,然后失败,并显示以下错误:
java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:98
Caused by: org.springframework.beans.factory.BeanCreationException at AbstractAutowireCapableBeanFactory.java:1804
Caused by: org.flywaydb.core.internal.exception.FlywaySqlException at JdbcUtils.java:68
Caused by: java.sql.SQLException at JdbcDatabaseContainer.java:263
Caused by: org.postgresql.util.PSQLException at ConnectionFactoryImpl.java:659
我知道这不可能是测试本身的问题,因为当我单独运行它时,没有问题:
./gradlew test --tests RandomTest
[...]
BUILD SUCCESSFUL in 16s
另外值得注意的是,我只有在使用Gradle运行测试时才遇到这个问题(本地和CI服务器上)。在IntelliJ中运行测试时,我没有遇到这个问题。
所以在我看来,这是某种资源问题,比如Testcontainers开始运行的Postgres示例,内存不足或连接不足或其他什么,但这只是猜测。
我尝试了在Testcontainers文档中找到的不同配置修改:
1.在守护进程模式下运行容器,如下所示:
spring:
datasource:
url: jdbc:tc:postgresql:9.6.8:///test?TC_DAEMON=true
1.通过设置TESTCONTAINERS_RYUK_DISABLED=true
禁用Ryuk
1.使用ryuk.container.privileged=true|false
显式地以(非)特权模式启动Ryuk(我尝试了两种方法,因为我不确定默认值是什么)
就我的问题而言,这些都没有明显的影响。
我在想,也许我们在太多的测试中过度使用了Testcontainers?我应该在大多数集成测试中使用H2,而只在少数选定的测试中使用Testcontainers,以确保所有测试都能与生产数据库一起工作吗?
还是我错过了什么?
1条答案
按热度按时间vecaoik11#
好吧,事实证明,这实际上是新增加的测试的问题。
测试作者添加了一个方法,该方法应该在测试之后清理数据库,如下所示:
当删除这个时,所有的测试都会再次正常工作。我猜这个清理比测试本身的执行时间要长一点,这样数据库连接就不能及时释放,以便下一个测试使用它,或者类似这样的事情。