Cucumber+Selenium Java集成Extent Report及并行执行问题咨询
问题解答:Cucumber + Selenium Java 报告升级与并行执行优化
一、Extent Reports 3.0.2 支持嵌入失败用例截图吗?当然支持!
你之前没成功大概率是监听逻辑的细节没处理到位,我给你贴一套可直接复用的核心代码:
1. 先补全Maven依赖
确保你的pom.xml里有这两个依赖(适配Extent 3.x版本的Cucumber集成包很关键):
<dependency> <groupId>com.aventstack</groupId> <artifactId>extentreports</artifactId> <version>3.0.2</version> </dependency> <dependency> <groupId>com.vimalselvam</groupId> <artifactId>cucumber-extentsreport</artifactId> <version>3.1.1</version> </dependency>
2. 自定义Extent监听类
这个类负责初始化报告、捕获场景状态,失败时自动嵌入截图:
import com.aventstack.extentreports.ExtentReports; import com.aventstack.extentreports.ExtentTest; import com.aventstack.extentreports.MediaEntityBuilder; import com.aventstack.extentreports.Status; import com.aventstack.extentreports.reporter.ExtentHtmlReporter; import cucumber.api.Scenario; import cucumber.api.java.After; import cucumber.api.java.Before; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; public class ExtentReportListener { private static ExtentReports extent; private ExtentTest currentScenario; // 初始化报告(建议在测试启动前执行,比如用@BeforeClass) public static void initReport() { ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter("target/extent-report.html"); extent = new ExtentReports(); extent.attachReporter(htmlReporter); } @Before public void startScenario(Scenario scenario) { // 为每个场景创建报告节点 currentScenario = extent.createTest(scenario.getName()); } @After public void endScenario(Scenario scenario) { if (scenario.isFailed()) { // 这里假设你用单例管理WebDriver,比如DriverManager.getDriver() WebDriver driver = DriverManager.getDriver(); byte[] screenshotBytes = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES); // 把截图嵌入到失败日志里 currentScenario.log(Status.FAIL, "场景执行失败", MediaEntityBuilder.createScreenCaptureFromBytes(screenshotBytes, scenario.getName()).build()); } else { currentScenario.log(Status.PASS, "场景执行成功"); } // 刷新报告 extent.flush(); } }
3. 在Cucumber Runner里注册监听
修改你的测试启动类,把自定义监听加进去:
import cucumber.api.CucumberOptions; import cucumber.api.junit.Cucumber; import org.junit.BeforeClass; import org.junit.runner.RunWith; @RunWith(Cucumber.class) @CucumberOptions( features = "src/test/resources/features", glue = "com.yourpackage.stepdefs", plugin = {"com.yourpackage.ExtentReportListener"} // 注册监听类 ) public class TestRunner { @BeforeClass public static void setupReport() { ExtentReportListener.initReport(); } }
注意:一定要保证WebDriver实例能被正确获取,用单例模式(比如DriverManager)管理是最稳妥的方式。
二、有没有更易配置的自定义报告?
当然有,给你推荐两个轻量化选项:
- Cucumber官方Pretty报告:零额外依赖,只需在Runner的
plugin里加"pretty", "html:target/cucumber-pretty-report",就能生成美观的基础报告,适合快速上手。 - Allure Reports:比Extent配置更标准化,可视化效果和历史趋势分析更强大,集成Cucumber只需要加少量依赖和Maven插件,社区文档也很完善。
三、三种并行执行方式的速度对比与配置
速度排序(从快到慢)
- TestNG Parallel Classes:速度最快,TestNG的线程调度机制直接基于Java线程池,对大规模测试用例的资源利用率最高。
- Cucumber JVM Parallel Plugin:专门为Cucumber场景设计,支持按场景/Feature拆分并行,比Surefire更适配Cucumber的执行模型,速度次之。
- Maven Surefire Plugin:通用测试执行插件,对Cucumber的并行仅支持测试类级别,灵活性和效率不如前两者,速度最慢。
各方式配置方法
1. TestNG Parallel Classes 配置
- 先把Cucumber Runner改成TestNG驱动:
import cucumber.api.CucumberOptions; import cucumber.api.testng.AbstractTestNGCucumberTests; @CucumberOptions( features = "src/test/resources/features", glue = "com.yourpackage.stepdefs" ) public class TestNGParallelRunner extends AbstractTestNGCucumberTests {}
- 创建
testng.xml配置并行规则:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="Cucumber Parallel Suite" parallel="classes" thread-count="5"> <test name="Parallel Test Suite"> <classes> <class name="com.yourpackage.TestNGParallelRunner"/> </classes> </test> </suite>
- Maven中指定用TestNG运行:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M7</version> <configuration> <suiteXmlFiles> <suiteXmlFile>testng.xml</suiteXmlFile> </suiteXmlFiles> </configuration> </plugin> </plugins> </build>
2. Cucumber JVM Parallel Plugin 配置
- 在
pom.xml中添加插件:
<build> <plugins> <plugin> <groupId>com.github.temyers</groupId> <artifactId>cucumber-jvm-parallel-plugin</artifactId> <version>5.0.0</version> <executions> <execution> <id>generate-runners</id> <phase>generate-test-sources</phase> <goals> <goal>generateRunners</goal> </goals> <configuration> <glue>com.yourpackage.stepdefs</glue> <featuresDirectory>src/test/resources/features</featuresDirectory> <outputDirectory>target/generated-test-sources/cucumber</outputDirectory> <parallelScheme>SCENARIO</parallelScheme> <!-- 按场景并行 --> <threadCount>5</threadCount> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M7</version> <configuration> <forkCount>5</forkCount> <reuseForks>true</reuseForks> <includes> <include>**/*IT.class</include> </includes> </configuration> </plugin> </plugins> </build>
3. Maven Surefire Plugin 并行配置
- 直接在Surefire插件中配置:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M7</version> <configuration> <parallel>classes</parallel> <!-- 按测试类并行 --> <threadCount>5</threadCount> <forkCount>5</forkCount> <reuseForks>true</reuseForks> </configuration> </plugin> </plugins> </build>
内容的提问来源于stack exchange,提问作者Aaditya Seshadri
相关产品推荐
相关产品推荐

