我正在尝试提高我正在进行的项目的Spring集成测试的性能。我们正在使用Spring + Gradle + JUnit。
在build.gradle
文件中使用此配置:
test {
useJUnit()
setForkEvery(0)
setMaxParallelForks(1)
}
我们能够在单个JVM中运行所有测试。虽然我认为这是默认行为。
但我一直在阅读Spring Test Context Caching并在我的application-test.yml中使用此属性:
logging:
level:
org:
springframework:
test:
context:
cache: DEBUG
我注意到在同一个类中运行的测试方法的以下日志
2017-09-05 08:33:11.829 DEBUG 5764 --- [ Test worker] c.DefaultCacheAwareContextLoaderDelegate : Storing ApplicationContext in cache under key [THIS HAD SENSITIVE DATA]
2017-09-05 08:33:11.830 DEBUG 5764 --- [ Test worker] org.springframework.test.context.cache : Spring test ApplicationContext cache statistics: [DefaultContextCache@572e81e7 size = 1, maxSize = 32, parentContextCount = 0, hitCount = 0, missCount = 1]
2017-09-05 08:33:11.849 DEBUG 5764 --- [ Test worker] c.DefaultCacheAwareContextLoaderDelegate : Retrieved ApplicationContext from cache with key [THIS HAD SENSITIVE DATA]
2017-09-05 08:33:11.850 DEBUG 5764 --- [ Test worker] org.springframework.test.context.cache : Spring test ApplicationContext cache statistics: [DefaultContextCache@572e81e7 size = 1, maxSize = 32, parentContextCount = 0, hitCount = 1, missCount = 1]
还有更多行说Retrieved ApplicationContext from cache with key...
。
对于在其他类中运行的测试方法,我注意到类似的日志,例如:
2017-09-05 08:33:12.971 DEBUG 10288 --- [ Test worker] c.DefaultCacheAwareContextLoaderDelegate : Storing ApplicationContext in cache under key [THIS HAD SENSITIVE DATA]
2017-09-05 08:33:12.971 DEBUG 10288 --- [ Test worker] org.springframework.test.context.cache : Spring test ApplicationContext cache statistics: [DefaultContextCache@2dad6721 size = 1, maxSize = 32, parentContextCount = 0, hitCount = 0, missCount = 1]
2017-09-05 08:33:13.194 DEBUG 10288 --- [ Test worker] c.DefaultCacheAwareContextLoaderDelegate : Retrieved ApplicationContext from cache with key [THIS HAD SENSITIVE DATA]
2017-09-05 08:33:13.194 DEBUG 10288 --- [ Test worker] org.springframework.test.context.cache : Spring test ApplicationContext cache statistics: [DefaultContextCache@2dad6721 size = 1, maxSize = 32, parentContextCount = 0, hitCount = 1, missCount = 1]
两个课程都注释均等:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles({"default", "profile-1", "profile-2"})
public class SomeControllerTest {
// Test methods...
}
我认为两个类中的测试方法应该可以共享相同的ApplicationContext
,从而减少测试持续的时间。但是,有可能这样做吗?如果是这样,怎么样?
我注意到两个ApplicationContext
对象大约在同一时间08:33:11.829
和08:33:12.971
存储在缓存中。 Test Runner是否在不同的线程或其他东西中执行测试?
答案 0 :(得分:4)
您的上下文实际上已缓存,但由于您使用Spring Boot的@MockBean
功能,因此实际上有两种不同的上下文。
@MockBean
的使用会导致每个ApplicationContext
具有不同的唯一键,在该下将其存储在上下文缓存中。
虽然这可能无法在任何地方公开记录,但实际上在org.springframework.boot.test.mock.mockito.MockitoContextCustomizerFactory
的实施中有内联文档:
我们在这里收集显式模拟定义,因为它们构成了MergedContextConfiguration键的一部分。不同的模拟需要有不同的密钥。
我已经针对Spring Boot打开了一个问题,记录了这种行为:https://github.com/spring-projects/spring-boot/issues/10182