Java 如何使用Maven(surefire或failsafe)运行并行Cucumber Spring引导集成测试?

Java 如何使用Maven(surefire或failsafe)运行并行Cucumber Spring引导集成测试?,java,cucumber,maven-surefire-plugin,maven-failsafe-plugin,cucumber-spring,Java,Cucumber,Maven Surefire Plugin,Maven Failsafe Plugin,Cucumber Spring,大家好, 我从今年1月开始开发Cumber测试,现在我面临着在Spring引导环境中与maven(surefire和failsafe)并行运行Cumber集成测试的问题 简而言之: 我想在运行spring boot应用程序的同时运行cucumber集成测试。 我使用maven时,Surefire或Failsafe插件处于活动状态。 当我注释掉代码中的每个Spring引导组件时,一切都正常。 然后我有和功能文件一样多的线程,它们并行运行。 但是,当我添加所需的Spring引导组件时,测试会以串行方

大家好,
我从今年1月开始开发Cumber测试,现在我面临着在Spring引导环境中与maven(surefire和failsafe)并行运行Cumber集成测试的问题

简而言之:
我想在运行spring boot应用程序的同时运行cucumber集成测试。 我使用maven时,Surefire或Failsafe插件处于活动状态。 当我注释掉代码中的每个Spring引导组件时,一切都正常。 然后我有和功能文件一样多的线程,它们并行运行。 但是,当我添加所需的Spring引导组件时,测试会以串行方式运行

pom.xml中的我的依赖项:

<dependencies>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-java</artifactId>
        <version>${cucumber.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-java8</artifactId>
        <version>${cucumber.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-junit</artifactId>
        <version>${cucumber.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-spring</artifactId>
        <version>${cucumber.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>${spring.boot.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>${spring.boot.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>${spring.boot.version}</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.30</version>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.200</version>
        <scope>test</scope>
    </dependency>
</dependencies>
<plugins>
    <!-- Maven Compiler -->
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
            <source>8</source>
            <target>8</target>
        </configuration>
    </plugin>
    <!-- Option 1 to run cucumber tests in parallel: Surefire -->
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.22.0</version>
        <configuration>
            <parallel>methods</parallel>
            <useUnlimitedThreads>true</useUnlimitedThreads>
        </configuration>
    </plugin>
    <!-- Option 2 to run cucumber tests in parallel: Failsafe -->
    <!--<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>3.0.0-M4</version>
        <executions>
            <execution>
                <goals>
                    <goal>integration-test</goal>
                    <goal>verify</goal>
                </goals>
                <configuration>
                    <parallel>methods</parallel>
                    <threadCount>5</threadCount>
                    <useUnlimitedThreads>false</useUnlimitedThreads>
                    &lt;!&ndash; important for the right execution &ndash;&gt;
                    <perCoreThreadCount>true</perCoreThreadCount>
                </configuration>
            </execution>
        </executions>
    </plugin>-->
</plugins>
StepDefinitions.java

TestApplication.java

CucumberSpringContextConfiguration.java

我的小黄瓜代码:

<dependencies>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-java</artifactId>
        <version>${cucumber.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-java8</artifactId>
        <version>${cucumber.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-junit</artifactId>
        <version>${cucumber.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-spring</artifactId>
        <version>${cucumber.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>${spring.boot.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>${spring.boot.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>${spring.boot.version}</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.30</version>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.200</version>
        <scope>test</scope>
    </dependency>
</dependencies>
<plugins>
    <!-- Maven Compiler -->
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
            <source>8</source>
            <target>8</target>
        </configuration>
    </plugin>
    <!-- Option 1 to run cucumber tests in parallel: Surefire -->
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.22.0</version>
        <configuration>
            <parallel>methods</parallel>
            <useUnlimitedThreads>true</useUnlimitedThreads>
        </configuration>
    </plugin>
    <!-- Option 2 to run cucumber tests in parallel: Failsafe -->
    <!--<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <version>3.0.0-M4</version>
        <executions>
            <execution>
                <goals>
                    <goal>integration-test</goal>
                    <goal>verify</goal>
                </goals>
                <configuration>
                    <parallel>methods</parallel>
                    <threadCount>5</threadCount>
                    <useUnlimitedThreads>false</useUnlimitedThreads>
                    &lt;!&ndash; important for the right execution &ndash;&gt;
                    <perCoreThreadCount>true</perCoreThreadCount>
                </configuration>
            </execution>
        </executions>
    </plugin>-->
</plugins>
场景-outline.feature

场景-1.1特征

场景-2.2特征

场景-3.2特征

预期行为:
每个功能文件一个线程,并行执行集成测试。 有些输出是这样的(这是我注释掉所有Spring引导内容时的输出):

实际行为:
只使用一个线程,所有测试都以串行方式运行。 输出:

我希望这个问题是可以理解的,有人可以帮助我

提前感谢,,

Maximotus

为了并行运行cucumber测试,您必须在pom.xml中添加
juni jupiter
junit vintage
的排除项。这就是它对我的作用:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.jupiter</groupId>
                    <artifactId>junit-jupiter</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

org.springframework.boot
弹簧起动试验
测试
org.junit.jupiter
朱尼特朱庇特
org.junit.vintage
朱尼特老式发动机

您可能希望使用
stepNotifications=false
重做所有操作。
stepNotifications
以许多不同的方式混淆了surefire/failsafe。使用
@CucumberContextConfiguration
时,您不再需要虚拟步骤定义。@M.P.Korstanje感谢这一提示,但它会产生相同的实际输出(对于failsafe和surefire)。我认为问题在于Spring Boot在某种程度上阻碍了多线程的上下文或其他方面。@M.P.Korstanje是的,你是对的。我把它拿走了。但还是一样的问题。正如预期的那样,输出中只缺少“INFO 13028---[main]p.CucumberSpringContextConfiguration:Spring Context已初始化以执行cucumber测试”的行。太棒了。我不久前写了测试来确认它的工作。你得深潜。
package parallel;
import io.cucumber.java.Before;
import io.cucumber.spring.CucumberContextConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.test.context.SpringBootContextLoader;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
/**
 * Class to use spring application context while running cucumber.
 */
@Slf4j
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ContextConfiguration(classes = TestApplication.class, loader = SpringBootContextLoader.class)
@CucumberContextConfiguration
public class CucumberSpringContextConfiguration {
    /**
     * Need this method so the cucumber will recognize this class as glue and load spring context configuration.
     */
    @Before
    public void setUp() {
        log.info("Spring Context initialized for executing cucumber tests.");
    }
}
Feature: Scenario Outlines feature file
  Scenario Outline: <scen_out_row_num>
    Given Step from '<scen_out_row_num>' in 'scenario-outlines' feature file
    Examples:
      | scen_out_row_num       |
      | Scenario Outline Row 1 |
      | Scenario Outline Row 2 |
Feature: Scenarios feature file
  Scenario: Scenario Number One -
    Given Step from 'Scenario 1' in 'scenarios-0' feature file
  Scenario: Scenario Number Two -
    Given Step from 'Scenario 2' in 'scenarios-0' feature file
Feature: Scenarios feature file
  Scenario: Scenario Number One a
    Given Step from 'Scenario 1' in 'scenarios-1' feature file
  Scenario: Scenario Number Two a
    Given Step from 'Scenario 2' in 'scenarios-1' feature file
Feature: Scenarios feature file
  Scenario: Scenario Number One b
    Given Step from 'Scenario 1' in 'scenarios-2' feature file
  Scenario: Scenario Number Two b
    Given Step from 'Scenario 2' in 'scenarios-2' feature file
Feature: Scenarios feature file
  Scenario: Scenario Number One c
    Given Step from 'Scenario 1' in 'scenarios-3' feature file
  Scenario: Scenario Number Two c
    Given Step from 'Scenario 2' in 'scenarios-3' feature file
[INFO] --- maven-failsafe-plugin:3.0.0-M4:integration-test (default) @ cucumber-test ---
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running Scenario Number One b
[pool-1-thread-4] INFO parallel.StepDefinitions -  Thread ID - 17 - Scenario 1 from scenarios-2 feature file.
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.338 s - in Scenario Number One b
[INFO] Running Scenario Number One a
[pool-1-thread-3] INFO parallel.StepDefinitions -  Thread ID - 16 - Scenario 1 from scenarios-1 feature file.
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.353 s - in Scenario Number One a
[INFO] Running Scenario Outline Row 1
[pool-1-thread-1] INFO parallel.StepDefinitions -  Thread ID - 14 - Scenario Outline Row 1 from scenario-outlines feature file.
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.363 s - in Scenario Outline Row 1
[INFO] Running Scenario Number One c
[pool-1-thread-5] INFO parallel.StepDefinitions -  Thread ID - 18 - Scenario 1 from scenarios-3 feature file.
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.371 s - in Scenario Number One c
[INFO] Running Scenario Number One -
[pool-1-thread-2] INFO parallel.StepDefinitions -  Thread ID - 15 - Scenario 1 from scenarios-0 feature file.
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.378 s - in Scenario Number One -
[INFO] Running Scenario Outline Row 2
[pool-1-thread-1] INFO parallel.StepDefinitions -  Thread ID - 14 - Scenario Outline Row 2 from scenario-outlines feature file.
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.003 s - in Scenario Outline Row 2
[INFO] Running Scenario Number Two a
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.011 s - in Scenario Number Two a
[INFO] Running Scenario Number Two c
[pool-1-thread-3] INFO parallel.StepDefinitions -  Thread ID - 16 - Scenario 2 from scenarios-1 feature file.
[pool-1-thread-5] INFO parallel.StepDefinitions -  Thread ID - 18 - Scenario 2 from scenarios-3 feature file.
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.017 s - in Scenario Number Two c
[INFO] Running Scenario Number Two b
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.027 s - in Scenario Number Two b
[INFO] Running Scenario Number Two -
[pool-1-thread-4] INFO parallel.StepDefinitions -  Thread ID - 17 - Scenario 2 from scenarios-2 feature file.
[pool-1-thread-2] INFO parallel.StepDefinitions -  Thread ID - 15 - Scenario 2 from scenarios-0 feature file.
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.043 s - in Scenario Number Two -


10
 Scenarios (
10 passed
)


10
 Steps (
10 passed
)


0m
10,486s
[INFO] --- maven-failsafe-plugin:3.0.0-M4:integration-test (default) @ cucumber-test ---
...    
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.4.RELEASE)
...
Thread ID - 1 - Scenario Outline Row 1 from scenario-outlines feature file.
2020-06-10 12:04:02.519  INFO 13028 --- [           main] o.s.t.c.support.AbstractContextLoader    : Could not detect default resource locations for test class [parallel.CucumberSpringContextConfiguration]: no resource found for suffixes {-context.xml, Context.groovy}.
...
2020-06-10 12:04:02.544  INFO 13028 --- [           main] parallel.StepDefinitions                 : 
... 
Thread ID - 1 - Scenario Outline Row 2 from scenario-outlines feature file.
2020-06-10 12:04:07.550  INFO 13028 --- [           main] o.s.t.c.support.AbstractContextLoader    : Could not detect default resource locations for test class [parallel.CucumberSpringContextConfiguration]: no resource found for suffixes {-context.xml, Context.groovy}.
Thread ID - 1 - Scenario 1 from scenarios-0 feature file.
...
Thread ID - 1 - Scenario 2 from scenarios-0 feature file.
...
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 10, Failures: 0, Errors: 0, Skipped: 0
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.jupiter</groupId>
                    <artifactId>junit-jupiter</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>