如何在Jenkins并行声明式流水线中生成Serenity聚合测试报告
Hey there! I see you're running multiple Serenity test scenarios in parallel with Jenkins Declarative Pipeline, and you want to combine those individual reports into one unified aggregated view. Let's walk through how to adjust your existing pipeline to make this happen smoothly.
Core Idea
Each parallel test run generates Serenity's raw result files (stored in target/site/serenity). Instead of only publishing each individual report, we'll first collect all these result files into a single shared location. Then we'll use Serenity's built-in aggregation goal to compile all results into one comprehensive report.
Step-by-Step Solution & Modified Pipeline
Here's your updated pipeline with aggregation support, with key changes highlighted via comments:
pipeline { agent { node ("cm-linux") } stages { stage('Prepare Shared Resources') { steps { // Optimize: Checkout code once here and stash it to avoid redundant git pulls in each parallel task deleteDir() checkout([$class: 'GitSCM', branches: [[name: '*/Ted']], doGenerateSubmoduleConfigurations: false, extensions: [], gitTool: 'GIT_windows', submoduleCfg: [], userRemoteConfigs: [[credentialsId: '<Credential>', url: '<GITHUB ADDRESS>']]]) stash includes: '**/*', name: 'test-code' // Create a dedicated directory to store all Serenity results from parallel tasks dir('serenity-results') { deleteDir() } } } stage('run-parallel-regression-testing') { steps { parallel( Run1_LoginPage: { node('cm-windows'){ withEnv(["JAVA_HOME=${tool '1.8.0.65_Windows'}", "PATH+MAVEN=${tool 'maven-3.0.4'}/bin"]){ deleteDir() // Unstash pre-checked out code instead of re-cloning unstash 'test-code' // Run tests to generate raw results (we'll aggregate later) bat 'mvn clean -Dtest=Run1_LoginPage -Dwebdriver.remote.url="<seleniumgrid hub address>" verify' // Stash the raw Serenity results for this task stash includes: 'target/site/serenity/**/*', name: 'serenity-results-LoginPage' // Keep publishing individual report if you still want access to it publishHTML([allowMissing: false, alwaysLinkToLastBuild: true, keepAll: true, reportDir: 'target\\site\\serenity', reportFiles: 'index.html', reportName: 'Run1_LoginPage']) } } }, Run2_SearchTab: { node('cm-windows'){ withEnv(["JAVA_HOME=${tool '1.8.0.65_Windows'}", "PATH+MAVEN=${tool 'maven-3.0.4'}/bin"]){ deleteDir() unstash 'test-code' bat 'mvn clean -Dtest=Run2_SearchTab -Dwebdriver.remote.url="<seleniumgrid hub address>" verify' stash includes: 'target/site/serenity/**/*', name: 'serenity-results-SearchTab' publishHTML([allowMissing: false, alwaysLinkToLastBuild: true, keepAll: true, reportDir: 'target\\site\\serenity', reportFiles: 'index.html', reportName: 'Run2_SearchTab']) } } }, Run4_AccountTab: { node('cm-windows'){ withEnv(["JAVA_HOME=${tool '1.8.0.65_Windows'}", "PATH+MAVEN=${tool 'maven-3.0.4'}/bin"]){ deleteDir() unstash 'test-code' bat 'mvn clean -Dtest=Run4_AccountTab -Dwebdriver.remote.url="<seleniumgrid hub address>" verify' stash includes: 'target/site/serenity/**/*', name: 'serenity-results-AccountTab' publishHTML([allowMissing: false, alwaysLinkToLastBuild: true, keepAll: true, reportDir: 'target\\site\\serenity', reportFiles: 'index.html', reportName: 'Run4_AccountTab']) } } }, Run3_CustomerTab: { node('cm-windows'){ withEnv(["JAVA_HOME=${tool '1.8.0.65_Windows'}", "PATH+MAVEN=${tool 'maven-3.0.4'}/bin"]){ deleteDir() unstash 'test-code' bat 'mvn clean -Dtest=Run3_CustomerTab -Dwebdriver.remote.url="<seleniumgrid hub address>" verify' stash includes: 'target/site/serenity/**/*', name: 'serenity-results-CustomerTab' publishHTML([allowMissing: false, alwaysLinkToLastBuild: true, keepAll: true, reportDir: 'target\\site\\serenity', reportFiles: 'index.html', reportName: 'Run3_CustomerTab']) } } } ) } } stage('Generate Aggregated Serenity Report') { steps { withEnv(["JAVA_HOME=${tool '1.8.0.65_Windows'}", "PATH+MAVEN=${tool 'maven-3.0.4'}/bin"]){ // Unstash all collected Serenity results into the shared directory dir('serenity-results') { unstash 'serenity-results-LoginPage' unstash 'serenity-results-SearchTab' unstash 'serenity-results-AccountTab' unstash 'serenity-results-CustomerTab' } // Run Serenity's aggregation goal to combine all results into one report // We specify the collected results directory with the -Dserenity.resultsDirectory flag bat 'mvn serenity:aggregate -Dserenity.resultsDirectory=serenity-results/target/site/serenity' // Publish the final aggregated report for easy access publishHTML([ allowMissing: false, alwaysLinkToLastBuild: true, keepAll: true, reportDir: 'target/site/serenity', reportFiles: 'index.html', reportName: 'Aggregated Serenity Test Report' ]) } } } } }
Key Details to Understand
- Shared Code Checkout: The
Prepare Shared Resourcesstage cuts down on redundant work by checking out your test code once and stashing it. Each parallel task then unstashes this code instead of re-cloning the repo. - Stashing Raw Results: Each parallel task stashes its
target/site/serenityfolder, which contains the raw test data Serenity needs to build aggregated reports (not just the static HTML). - Aggregation Stage: After all parallel tests finish, we gather all stashed results and run
mvn serenity:aggregate. This command compiles all individual test results into a single report with combined statistics, trends, and scenario summaries. - Dual Report Access: You still keep access to individual scenario reports if you need to drill down into specific test failures, while also having the aggregated view for a high-level overview.
Quick Notes
- Ensure your Serenity Maven plugin in
pom.xmlis up-to-date (most recent versions support aggregation out of the box). - If you add more test scenarios later, just add corresponding stash/unstash steps for each in the aggregation stage.
- You can adjust the
serenity-resultsdirectory path if needed—just keep it consistent across all stages.
内容的提问来源于stack exchange,提问作者Stephen Zhou

