使用 Cucumber 和 SpringBoot 进行每次测试的数据源

Posted

技术标签:

【中文标题】使用 Cucumber 和 SpringBoot 进行每次测试的数据源【英文标题】:DataSource per test with Cucumber and SpringBoot 【发布时间】:2018-11-30 11:42:11 【问题描述】:

我有一个带有弹簧靴的黄瓜测试设置。有大量的集成测试需要一段时间才能运行。因为它们共享一个数据库,所以 cucumber 4+ 中的新线程模式不起作用(如预期的那样)。

理想情况下,这也适用于 Junit。

对于每个测试,我想创建一个动态数据源,其中包含一个新的数据库/数据源实例,测试可以独立于其他实例使用,允许它运行多线程(并使用我可用的 12 个内核)。

我在 DataSource bean 上尝试过 @Scope("cucumber-glue")@Scope("prototype"),但这会导致 org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'dataSource': Requested bean is currently in creation: Is there an unresolvable circular reference?

如果我使用原型作用域,每次都会调用 bean 创建方法,但会出现此错误,胶水作用域也是如此。

我还在类和方法中添加了@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD),但没有范围,但这似乎无济于事。

有没有办法可以: 1.为每个测试创建一个新的数据源并让hibernate创建表? 2. 汇集一组可供测试使用的数据源? 3. 相应地填充/重新初始化上下文?

这样做的一个副作用是,我不相信我的上下文在针对范围界定的其他实例的测试之间被正确地重新创建。

@Configuration
public class H2DynamicDataSource 

@Autowired
private Environment env;

@Bean
@Scope("prototype")
public DataSource dataSource() 
    return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.H2)
            .build();



干杯 回复

【问题讨论】:

【参考方案1】:

希望你已经解决了这个问题。 我刚刚经历了类似的事情,想在 SlackOverflow 周围巡游,看看是否有人在做类似的事情(或者可能询问如何做这样的事情)并看到了这篇文章。认为这是一个放弃此信息的好地方,以防其他人试图走这条路。

我想你问了两个问题:

    如何使用 Cucumber 和 Junit Cucumber 实现多线程?

    多线程效果很好,但你被限制在一个通道上 如果您使用 CucumberSpringJUnit4ClassRunner runner junit runner 课程。 (我怀疑这就是@CucumberOptions 不包含线程arg 的原因。它对当前的Cucumber runner 实现毫无用处。)

    为了让这个工作,我必须编写自己的测试运行器 会将整个测试执行推迟到 Cucumbers Runtime 目的。我使用了一个自定义黄瓜插件来缓存结果和 然后在被要求“运行”时将这些结果转发回junit 个别测试。黄瓜在车轮后面,我能够允许 用于我的测试的任意数量的线程。

    如何确保每次测试都有新的spring数据源?

    如果您不熟悉 Spring 缓存的测试上下文是如何进行测试的,您应该查看这里的文档 https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#testcontext-ctx-management-caching,但是 tl;dr: Spring 的 TestContextManager(这是 Springs junit runner 的底层内容)将在由您的测试配置键入的映射中创建和存储弹簧上下文。 DirtiesContext 将强制上下文重新加载.. 但否则具有相同父类的两个测试可以有效地保证在相同的测试上下文中执行。如果您的数据源是在启动期间初始化的 Spring 数据源。您肯定需要在测试之间刷新此上下文。

将这两个概念放在一起.. Cucumber-Spring 提供了一种为每个测试创建新上下文(与每个测试设计的黄瓜新“世界”一致)的方法,但它通过忽略任何现有的 spring 上下文或其中包含的数据来实现.如果您可以信任 Cucumber-Spring 为您正确地建立您的数据源,这实际上可能对您有所帮助。但在我的情况下,我们在使用这个假上下文时遇到了很多问题,并且确实需要从默认的 spring 上下文中提取对象。在我的情况下,我必须将 Springs TestContextManager 合并到我的自定义插件中并编写我自己的 Cucumber BackendSupplierimplementation 来劫持 Cucumbers 依赖注入机制(有效地替换 Cucumber-Spring)

总而言之,您尝试做的是一个主要的 PITA,我希望 Cucumber 的人在某个时候让这变得更容易.. 但您尝试做的绝对是可能的。希望你能成功!

【讨论】:

谢谢,这是一个很好的细分。事实证明,我遇到的问题与我认为的问题不同。当我很高兴地从 cucumber 访问数据库时,我正在通过一个 mq 更新它,它在不同的事务中运行,所以不允许我正确回滚。最后我手动拆了。希望这可以帮助某人

以上是关于使用 Cucumber 和 SpringBoot 进行每次测试的数据源的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Eclipse 中使用 Gradle 运行 Cucumber + Spring Boot 应用程序

从 Spring Boot 应用程序启动的 Cucumber 未在 jar 中找到胶水类

修复 IntelliJ IDEA 中 Cucumber 6.8.1运行找不到类的问题

春季启动黄瓜测试

无法使用 Cucumber 和 TestNG 在 xml 文件上传递参数

RSpec 和 Cucumber 有啥区别? [关闭]