在多线程执行期间使用 TestNG 生成 Cucumber ExtentReport
Cucumber ExtentReport generation with TestNG during multiple thread execution
我正在 运行使用 Cucumber 和 TestNG 在移动设备上并行测试。我的 TestNG 运行ner class 如下所示。
@CucumberOptions(
features="src/test/resources/features",
glue={"org.cucumber.stepdefs"},
plugin = {
"com.cucumber.listener.ExtentCucumberFormatter:" }, monochrome = true)
public class TestRunner extends BaseTest {
private static TestNGCucumberRunner testRunner;
@BeforeClass
public void setUP() {
System.out.println("Thread = " + Thread.currentThread().getId() + " - object hash = " + this.hashCode());
testRunner = new TestNGCucumberRunner(TestRunner.class);
ExtentProperties extentProperties = ExtentProperties.INSTANCE;
extentProperties.setReportPath("output/" + this.hashCode() + "-report.html");
}
@Test(description="Tests",dataProvider="features")
public void setUpClass(CucumberFeatureWrapper cFeature) {
testRunner.runCucumber(cFeature.getCucumberFeature());
}
@DataProvider(name="features")
public Object[][] getFeatures() {
return testRunner.provideFeatures();
}
@AfterClass
public static void teardown() {
testRunner.finish();
}
}
按预期工作 - 我的 Cucumber 测试是 运行 在每个连接设备的单独线程上并行进行的(在我的 testng.xml 文件中定义)。
我正在使用 ExtentReports 在每个 运行 之后生成报告,但目前我只得到一个报告,我想为每个 运行ning 线程生成一个单独的报告.
我不明白为什么会这样。我添加了控制台打印以检查每个 运行ning 线程是否有 TestRunner class 的瞬间,并且确实存在 - 运行 之后我的控制台日志包含以下内容(假设连接了 2 个移动设备):
Thread = 33 - object hash = 923219673
Thread = 32 - object hash = 280884709
所以这正如我预期的那样工作,除了在生成报告时,只创建了一份包含所有测试数据的报告。我假设因为我在 setUp()
方法中将报告路径设置为每个线程中的唯一文件名,所以应该为每个线程创建一个报告?
似乎在生成报告时,Cucumber ExtendReport 插件会等待所有测试完成并默认生成批量报告。这个对吗?如果是这样,我该如何更改?
下面是我的 pom.xml
文件的主要部分,用于提供额外的配置信息。
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-java -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>1.2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-jvm -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-jvm</artifactId>
<version>4.2.0</version>
<type>pom</type>
</dependency>
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-testng -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-testng</artifactId>
<version>1.2.5</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-picocontainer -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>1.2.5</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-server -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>3.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager -->
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>1.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.aventstack/extentreports -->
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>com.vimalselvam</groupId>
<artifactId>cucumber-extentsreport</artifactId>
<version>3.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-junit -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>1.2.5</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.appium/java-client -->
<!-- https://mvnrepository.com/artifact/io.appium/java-client -->
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>6.0.0-BETA3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<parallel>tests</parallel>
<threadCount>10</threadCount>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
@BeforeClass
public void setUP() {
System.out.println("Thread = " + Thread.currentThread().getId() + " - object hash = " + this.hashCode());
testRunner = new TestNGCucumberRunner(TestRunner.class);
ExtentProperties extentProperties = ExtentProperties.INSTANCE;
extentProperties.setReportPath("output/" + this.hashCode() + "-report.html");
}
此设置方法被并行调用两次。如果您要在这些线程之间共享的 ExtentProperties.INSTANCE
上更改 setReportPath
。所以线程正在覆盖彼此的结果。您可以通过打印 ExtentProperties.INSTANCE
.
的散列来验证这一点
我正在 运行使用 Cucumber 和 TestNG 在移动设备上并行测试。我的 TestNG 运行ner class 如下所示。
@CucumberOptions(
features="src/test/resources/features",
glue={"org.cucumber.stepdefs"},
plugin = {
"com.cucumber.listener.ExtentCucumberFormatter:" }, monochrome = true)
public class TestRunner extends BaseTest {
private static TestNGCucumberRunner testRunner;
@BeforeClass
public void setUP() {
System.out.println("Thread = " + Thread.currentThread().getId() + " - object hash = " + this.hashCode());
testRunner = new TestNGCucumberRunner(TestRunner.class);
ExtentProperties extentProperties = ExtentProperties.INSTANCE;
extentProperties.setReportPath("output/" + this.hashCode() + "-report.html");
}
@Test(description="Tests",dataProvider="features")
public void setUpClass(CucumberFeatureWrapper cFeature) {
testRunner.runCucumber(cFeature.getCucumberFeature());
}
@DataProvider(name="features")
public Object[][] getFeatures() {
return testRunner.provideFeatures();
}
@AfterClass
public static void teardown() {
testRunner.finish();
}
}
按预期工作 - 我的 Cucumber 测试是 运行 在每个连接设备的单独线程上并行进行的(在我的 testng.xml 文件中定义)。
我正在使用 ExtentReports 在每个 运行 之后生成报告,但目前我只得到一个报告,我想为每个 运行ning 线程生成一个单独的报告.
我不明白为什么会这样。我添加了控制台打印以检查每个 运行ning 线程是否有 TestRunner class 的瞬间,并且确实存在 - 运行 之后我的控制台日志包含以下内容(假设连接了 2 个移动设备):
Thread = 33 - object hash = 923219673
Thread = 32 - object hash = 280884709
所以这正如我预期的那样工作,除了在生成报告时,只创建了一份包含所有测试数据的报告。我假设因为我在 setUp()
方法中将报告路径设置为每个线程中的唯一文件名,所以应该为每个线程创建一个报告?
似乎在生成报告时,Cucumber ExtendReport 插件会等待所有测试完成并默认生成批量报告。这个对吗?如果是这样,我该如何更改?
下面是我的 pom.xml
文件的主要部分,用于提供额外的配置信息。
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-java -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>1.2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-jvm -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-jvm</artifactId>
<version>4.2.0</version>
<type>pom</type>
</dependency>
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-testng -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-testng</artifactId>
<version>1.2.5</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-picocontainer -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>1.2.5</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-server -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>3.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager -->
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>1.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.aventstack/extentreports -->
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>com.vimalselvam</groupId>
<artifactId>cucumber-extentsreport</artifactId>
<version>3.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-junit -->
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>1.2.5</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.appium/java-client -->
<!-- https://mvnrepository.com/artifact/io.appium/java-client -->
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>6.0.0-BETA3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19</version>
<configuration>
<parallel>tests</parallel>
<threadCount>10</threadCount>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
@BeforeClass
public void setUP() {
System.out.println("Thread = " + Thread.currentThread().getId() + " - object hash = " + this.hashCode());
testRunner = new TestNGCucumberRunner(TestRunner.class);
ExtentProperties extentProperties = ExtentProperties.INSTANCE;
extentProperties.setReportPath("output/" + this.hashCode() + "-report.html");
}
此设置方法被并行调用两次。如果您要在这些线程之间共享的 ExtentProperties.INSTANCE
上更改 setReportPath
。所以线程正在覆盖彼此的结果。您可以通过打印 ExtentProperties.INSTANCE
.