1. 程式人生 > >testng+Extentreport監聽器出測試報告

testng+Extentreport監聽器出測試報告

監聽器:

  1 package listener;
  2 
  3 import com.aventstack.extentreports.ExtentReports;
  4 import com.aventstack.extentreports.ExtentTest;
  5 import com.aventstack.extentreports.ResourceCDN;
  6 import com.aventstack.extentreports.Status;
  7 import com.aventstack.extentreports.model.TestAttribute;
8 import com.aventstack.extentreports.reporter.ExtentHtmlReporter; 9 import com.aventstack.extentreports.reporter.configuration.ChartLocation; 10 import com.aventstack.extentreports.reporter.configuration.Theme; 11 import org.testng.*; 12 import org.testng.xml.XmlSuite; 13 14 import java.io.File;
15 import java.util.*; 16 17 public class ExtentTestNGIReportListener implements IReporter { 18 19 //生成的路徑以及檔名 20 private static final String OUTPUT_FOLDER = "test-output/"; 21 private static final String FILE_NAME = "meiju_apitest.html"; 22 23 private ExtentReports extent; 24
25 @Override 26 public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) { 27 init(); 28 boolean createSuiteNode = false; 29 if(suites.size()>1){ 30 createSuiteNode=true; 31 } 32 for (ISuite suite : suites) { 33 Map<String, ISuiteResult> result = suite.getResults(); 34 //如果suite裡面沒有任何用例,直接跳過,不在報告裡生成 35 if(result.size()==0){ 36 continue; 37 } 38 //統計suite下的成功、失敗、跳過的總用例數 39 int suiteFailSize=0; 40 int suitePassSize=0; 41 int suiteSkipSize=0; 42 ExtentTest suiteTest=null; 43 //存在多個suite的情況下,在報告中將同一個一個suite的測試結果歸為一類,建立一級節點。 44 if(createSuiteNode){ 45 suiteTest = extent.createTest(suite.getName()).assignCategory(suite.getName()); 46 } 47 boolean createSuiteResultNode = false; 48 if(result.size()>1){ 49 createSuiteResultNode=true; 50 } 51 for (ISuiteResult r : result.values()) { 52 ExtentTest resultNode; 53 ITestContext context = r.getTestContext(); 54 if(createSuiteResultNode){ 55 //沒有建立suite的情況下,將在SuiteResult的建立為一級節點,否則建立為suite的一個子節點。 56 if( null == suiteTest){ 57 resultNode = extent.createTest(r.getTestContext().getName()); 58 }else{ 59 resultNode = suiteTest.createNode(r.getTestContext().getName()); 60 } 61 }else{ 62 resultNode = suiteTest; 63 } 64 if(resultNode != null){ 65 resultNode.getModel().setName(suite.getName()+" : "+r.getTestContext().getName()); 66 if(resultNode.getModel().hasCategory()){ 67 resultNode.assignCategory(r.getTestContext().getName()); 68 }else{ 69 resultNode.assignCategory(suite.getName(),r.getTestContext().getName()); 70 } 71 resultNode.getModel().setStartTime(r.getTestContext().getStartDate()); 72 resultNode.getModel().setEndTime(r.getTestContext().getEndDate()); 73 //統計SuiteResult下的資料 74 int passSize = r.getTestContext().getPassedTests().size(); 75 int failSize = r.getTestContext().getFailedTests().size(); 76 int skipSize = r.getTestContext().getSkippedTests().size(); 77 suitePassSize += passSize; 78 suiteFailSize += failSize; 79 suiteSkipSize += skipSize; 80 if(failSize>0){ 81 resultNode.getModel().setStatus(Status.FAIL); 82 } 83 resultNode.getModel().setDescription(String.format("Pass: %s ; Fail: %s ; Skip: %s ;",passSize,failSize,skipSize)); 84 } 85 buildTestNodes(resultNode,context.getFailedTests(), Status.FAIL); 86 buildTestNodes(resultNode,context.getSkippedTests(), Status.SKIP); 87 buildTestNodes(resultNode,context.getPassedTests(), Status.PASS); 88 } 89 if(suiteTest!= null){ 90 suiteTest.getModel().setDescription(String.format("Pass: %s ; Fail: %s ; Skip: %s ;",suitePassSize,suiteFailSize,suiteSkipSize)); 91 if(suiteFailSize>0){ 92 suiteTest.getModel().setStatus(Status.FAIL); 93 } 94 } 95 96 } 97 // for (String s : Reporter.getOutput()) { 98 // extent.setTestRunnerOutput(s); 99 // } 100 101 extent.flush(); 102 } 103 104 private void init() { 105 //資料夾不存在的話進行建立 106 File reportDir= new File(OUTPUT_FOLDER); 107 if(!reportDir.exists()&& !reportDir .isDirectory()){ 108 reportDir.mkdir(); 109 } 110 ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(OUTPUT_FOLDER + FILE_NAME); 111 // 設定靜態檔案的DNS 112 //怎麼樣解決cdn.rawgit.com訪問不了的情況 113 htmlReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS); 114 115 htmlReporter.config().setDocumentTitle("api自動化測試報告"); 116 htmlReporter.config().setReportName("api自動化測試報告"); 117 htmlReporter.config().setChartVisibilityOnOpen(true); 118 htmlReporter.config().setTestViewChartLocation(ChartLocation.TOP); 119 htmlReporter.config().setTheme(Theme.STANDARD); 120 htmlReporter.config().setCSS(".node.level-1 ul{ display:none;} .node.level-1.active ul{display:block;}"); 121 extent = new ExtentReports(); 122 extent.attachReporter(htmlReporter); 123 extent.setReportUsesManualConfiguration(true); 124 } 125 126 private void buildTestNodes(ExtentTest extenttest, IResultMap tests, Status status) { 127 //存在父節點時,獲取父節點的標籤 128 String[] categories=new String[0]; 129 if(extenttest != null ){ 130 List<TestAttribute> categoryList = extenttest.getModel().getCategoryContext().getAll(); 131 categories = new String[categoryList.size()]; 132 for(int index=0;index<categoryList.size();index++){ 133 categories[index] = categoryList.get(index).getName(); 134 } 135 } 136 137 ExtentTest test; 138 139 if (tests.size() > 0) { 140 //調整用例排序,按時間排序 141 Set<ITestResult> treeSet = new TreeSet<ITestResult>(new Comparator<ITestResult>() { 142 @Override 143 public int compare(ITestResult o1, ITestResult o2) { 144 return o1.getStartMillis()<o2.getStartMillis()?-1:1; 145 } 146 }); 147 treeSet.addAll(tests.getAllResults()); 148 for (ITestResult result : treeSet) { 149 Object[] parameters = result.getParameters(); 150 String name=""; 151 //如果有引數,則使用引數的toString組合代替報告中的name 152 for(Object param:parameters){ 153 name+=param.toString(); 154 } 155 if(name.length()>0){ 156 if(name.length()>50){ 157 name= name.substring(0,49)+"..."; 158 } 159 }else{ 160 name = result.getMethod().getMethodName(); 161 } 162 if(extenttest==null){ 163 test = extent.createTest(name); 164 }else{ 165 //作為子節點進行建立時,設定同父節點的標籤一致,便於報告檢索。 166 test = extenttest.createNode(name).assignCategory(categories); 167 } 168 //test.getModel().setDescription(description.toString()); 169 //test = extent.createTest(result.getMethod().getMethodName()); 170 for (String group : result.getMethod().getGroups()) 171 test.assignCategory(group); 172 173 List<String> outputList = Reporter.getOutput(result); 174 for(String output:outputList){ 175 //將用例的log輸出報告中 176 test.debug(output); 177 } 178 if (result.getThrowable() != null) { 179 test.log(status, result.getThrowable()); 180 } 181 else { 182 test.log(status, "Test " + status.toString().toLowerCase() + "ed"); 183 } 184 185 test.getModel().setStartTime(getTime(result.getStartMillis())); 186 test.getModel().setEndTime(getTime(result.getEndMillis())); 187 } 188 } 189 } 190 191 private Date getTime(long millis) { 192 Calendar calendar = Calendar.getInstance(); 193 calendar.setTimeInMillis(millis); 194 return calendar.getTime(); 195 } 196 }

 

testng.xml:

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
 3 
 4 <suite name="測試套件1">
 5 
 6     <test name="login">
 7 
 8         <classes>
 9             <class name="xxx.suite.SuiteConfig"/>
10             <class name="xxx.login.ToLogin"/>
11             <class name="xxx.login.LoginIn"/>
12             <class name="xxx.login.GetCurrentUser"/>
13             <class name="xxx.login.LoginOut"></class>
14             <class name="xxx.objectLibrary.GetLibraryDetailById"></class>
15 
16         </classes>
17     </test>
18     <listeners>
19         <!--<listener class-name="com.vimalselvam.testng.listener.ExtentTestNgFormatter"/>-->
20         <listener class-name="listener.ExtentTestNGIReportListener"/>
21     </listeners>
22 </suite>

 pom.xml:jar包

 1         <!-- extentreports -->
 2         <dependency>
 3             <groupId>com.relevantcodes</groupId>
 4             <artifactId>extentreports</artifactId>
 5             <version>2.41.1</version>
 6         </dependency>
 7         <dependency>
 8             <groupId>com.vimalselvam</groupId>
 9             <artifactId>testng-extentsreport</artifactId>
10             <version>1.3.1</version>
11         </dependency>
12         <dependency>
13             <groupId>com.aventstack</groupId>
14             <artifactId>extentreports</artifactId>
15             <version>3.0.6</version>
16         </dependency>
17         <!-- extentreports -->

 

生成的測試報告的樣式:

 

可以監聽到testng中執行的案例,數量,通過,失敗,失敗日誌,按分組篩選展示等資訊;

 需修改下,第113行程式碼:

//怎麼樣解決cdn.rawgit.com訪問不了的情況
htmlReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS);