运行 套件并行使用 Maven 故障安全
run suites in parallel using maven failsafe
我正在尝试 运行 我的并行测试,我有一个与我能够找到的所有其他用例不同的用例。
我的测试非常简单明了,如下所示:
src/test/java
+-features.areaA
| +-SomeStory.java
| +-AnotherStory.java
| ...
+-features.areaB
| +-DifferentStory.java
| +-OtherStory.java
| ...
...
测试是使用 serenity-bdd, which is a wrapper for selenium, and the test manager is junit4 编写的。
每个“区域”代表被测应用程序的一些独立区域。一个区域内的测试不能 运行 并行,因为它们会破坏他们正在使用的数据。但是,不同区域之间的测试当然可以 运行 并行进行,因为没有碰撞。
我尝试配置我的 maven-failsafe-plugin according to the documentation。使用 parallel=suites
和 threadCount=4
、threadCountSuites=4
或 useUnlimitedThreads=true
中的任何一个,导致一次只有一个测试 运行。
在 Failsafe 插件的上下文中,我对“套件”的理解有误吗?是否可以并行化测试,以便将整个包一次一个地送入 VM 线程,但在一个包中 类 按顺序 运行?
更新:
- Maven 故障安全版本 2.22.2
- JUnit 版本 4.13
maven-failsafe-plugin has no notion of "packages". The notion of "suites" is related to junit4 Suite.
为了解决我上面的问题,我做了以下事情:
在每个“features.area”中我创建了一个“TestSuiteStub”:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
/**
* This will be processed by groovy-maven-plugin.
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({
/* add test Stories after this ANCHOR */
})
public class TestSuiteStub {
/* Suite holder */
}
然后我将 groovy-maven-plugin 与 execute
目标和以下脚本一起使用:
// find all TestSuiteStub.java
new File("${project.build.testSourceDirectory}/features"). // exploits the "complication" in Maven interpolation and GStrings
traverse(type: groovy.io.FileType.FILES, nameFilter: ~/TestSuiteStub\.java/) { stub ->
println 'Using: ' + stub
// in the same dir as TestSuiteStub.java, find all *Story.java
def stories = new StringBuilder()
new File(stub.parent).
eachFileMatch(groovy.io.FileType.FILES, ~/.*Story\.java/) { story ->
stories.append story.name.replace('java', 'class')
stories.append ', ' // will leave a comma at end of list, but javac seems to be ok with that
}
println 'Found: ' + stories
// write out TestSuite.java
def suite = new File(stub.parent + '/TestSuite.java')
suite.delete()
println 'Writing: ' + suite
stub.eachLine() { line ->
if(line.contains('Stub'))
suite.append line.replace('TestSuiteStub', 'TestSuite') + System.getProperty('line.separator')
else
suite.append line + System.getProperty('line.separator')
if(line.contains('ANCHOR'))
suite.append stories + System.getProperty('line.separator')
}
}
这将处理每个 TestSuiteStub 并生成一个 TestSuite。所以在 运行ning 这个之后(你可以使用 mvn test-compile
到 运行 这个,而不用 运行ning 你的测试),我有这样的东西:
src/test/java
+-features.areaA
| +-SomeStory.java
| +-AnotherStory.java
| ...
| +-TestSuiteStub.java
| +-TestSuite.java
+-features.areaB
| +-DifferentStory.java
| +-OtherStory.java
| ...
| +-TestSuiteStub.java
| +-TestSuite.java
...
第一个测试套件看起来像这样:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
/**
* This class will be processed by groovy-maven-plugin.
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({
/* add test Stories after this ANCHOR */
SomeStory.class, AnotherStory.class,
})
public class TestSuite {
/* Suite holder */
}
为了 maven-failsafe-plugin 选择它,我这样配置它:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${failsafe.plugin.version}</version>
<configuration>
<includes>
<include>features.*.*Suite</include>
</includes>
<parallel>suites</parallel>
<threadCountSuites>4</threadCountSuites>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
最后我还添加了 *Suite.java
到我的 .gitignore
。
我正在尝试 运行 我的并行测试,我有一个与我能够找到的所有其他用例不同的用例。
我的测试非常简单明了,如下所示:
src/test/java
+-features.areaA
| +-SomeStory.java
| +-AnotherStory.java
| ...
+-features.areaB
| +-DifferentStory.java
| +-OtherStory.java
| ...
...
测试是使用 serenity-bdd, which is a wrapper for selenium, and the test manager is junit4 编写的。
每个“区域”代表被测应用程序的一些独立区域。一个区域内的测试不能 运行 并行,因为它们会破坏他们正在使用的数据。但是,不同区域之间的测试当然可以 运行 并行进行,因为没有碰撞。
我尝试配置我的 maven-failsafe-plugin according to the documentation。使用 parallel=suites
和 threadCount=4
、threadCountSuites=4
或 useUnlimitedThreads=true
中的任何一个,导致一次只有一个测试 运行。
在 Failsafe 插件的上下文中,我对“套件”的理解有误吗?是否可以并行化测试,以便将整个包一次一个地送入 VM 线程,但在一个包中 类 按顺序 运行?
更新:
- Maven 故障安全版本 2.22.2
- JUnit 版本 4.13
maven-failsafe-plugin has no notion of "packages". The notion of "suites" is related to junit4 Suite.
为了解决我上面的问题,我做了以下事情:
在每个“features.area”中我创建了一个“TestSuiteStub”:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
/**
* This will be processed by groovy-maven-plugin.
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({
/* add test Stories after this ANCHOR */
})
public class TestSuiteStub {
/* Suite holder */
}
然后我将 groovy-maven-plugin 与 execute
目标和以下脚本一起使用:
// find all TestSuiteStub.java
new File("${project.build.testSourceDirectory}/features"). // exploits the "complication" in Maven interpolation and GStrings
traverse(type: groovy.io.FileType.FILES, nameFilter: ~/TestSuiteStub\.java/) { stub ->
println 'Using: ' + stub
// in the same dir as TestSuiteStub.java, find all *Story.java
def stories = new StringBuilder()
new File(stub.parent).
eachFileMatch(groovy.io.FileType.FILES, ~/.*Story\.java/) { story ->
stories.append story.name.replace('java', 'class')
stories.append ', ' // will leave a comma at end of list, but javac seems to be ok with that
}
println 'Found: ' + stories
// write out TestSuite.java
def suite = new File(stub.parent + '/TestSuite.java')
suite.delete()
println 'Writing: ' + suite
stub.eachLine() { line ->
if(line.contains('Stub'))
suite.append line.replace('TestSuiteStub', 'TestSuite') + System.getProperty('line.separator')
else
suite.append line + System.getProperty('line.separator')
if(line.contains('ANCHOR'))
suite.append stories + System.getProperty('line.separator')
}
}
这将处理每个 TestSuiteStub 并生成一个 TestSuite。所以在 运行ning 这个之后(你可以使用 mvn test-compile
到 运行 这个,而不用 运行ning 你的测试),我有这样的东西:
src/test/java
+-features.areaA
| +-SomeStory.java
| +-AnotherStory.java
| ...
| +-TestSuiteStub.java
| +-TestSuite.java
+-features.areaB
| +-DifferentStory.java
| +-OtherStory.java
| ...
| +-TestSuiteStub.java
| +-TestSuite.java
...
第一个测试套件看起来像这样:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
/**
* This class will be processed by groovy-maven-plugin.
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({
/* add test Stories after this ANCHOR */
SomeStory.class, AnotherStory.class,
})
public class TestSuite {
/* Suite holder */
}
为了 maven-failsafe-plugin 选择它,我这样配置它:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${failsafe.plugin.version}</version>
<configuration>
<includes>
<include>features.*.*Suite</include>
</includes>
<parallel>suites</parallel>
<threadCountSuites>4</threadCountSuites>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
最后我还添加了 *Suite.java
到我的 .gitignore
。