在使用 Spring 引导的每个 Cucumber 场景之后回滚事务

Rollback transactions after each Cucumber scenarios with Spring Boot

我正在使用带有 Spring Boot 2.5 的 BDD 测试框架 Cucumber。 我想在每个 Cucumber 场景之后回滚事务或重置我的数据库。我正在使用 H2 数据库,由动态生成的数据填充。 我尝试了@Transactional,但它不起作用并且@DirtiesContext 很慢。

这样做的方法是使用PlatformTransactionManager在每个场景之前启动事务并在之后回滚。这基本上就是 TransactionalTestExecutionListener 在执行带有 @Transactional 注释的 JUnit 测试 class 时所做的。

在 Cucumber 中,您可以使用 @Before@After 挂钩来执行此操作。因为您可能不想对每个场景都这样做,所以您可以选择使挂钩有条件,以便它们仅在以正确方式标记场景时执行。

例如:

@txn
Feature: Search

  Background:
    Given there is a user

  Scenario: Find messages by content
    Given a User has posted the following messages:
      | content            |
      | I am making dinner |
      | I just woke up     |
      | I am going to work |
    When I search for "I am"
    Then the results content should be:
      | I am making dinner |
      | I am going to work |
public class SpringTransactionHooks implements BeanFactoryAware {

    private BeanFactory beanFactory;
    private TransactionStatus transactionStatus;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    @Before(value = "@txn", order = 100)
    public void startTransaction() {
        transactionStatus = beanFactory.getBean(PlatformTransactionManager.class)
                .getTransaction(new DefaultTransactionDefinition());
    }
    
    @After(value = "@txn", order = 100)
    public void rollBackTransaction() {
        beanFactory.getBean(PlatformTransactionManager.class)
                .rollback(transactionStatus);
    }

}

发件人:

https://github.com/cucumber/cucumber-jvm/tree/main/examples/spring-java-junit5