1 package org.apache.maven.plugins.surefire.report;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.text.NumberFormat;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Locale;
30 import java.util.Map;
31
32 import javax.xml.parsers.ParserConfigurationException;
33
34 import org.apache.maven.reporting.MavenReportException;
35 import org.apache.maven.shared.utils.StringUtils;
36 import org.apache.maven.shared.utils.io.DirectoryScanner;
37 import org.xml.sax.SAXException;
38
39
40
41
42 public class SurefireReportParser
43 {
44 private static final String INCLUDES = "*.xml";
45
46 private static final String EXCLUDES = "*.txt, testng-failed.xml, testng-failures.xml, testng-results.xml, failsafe-summary*.xml";
47
48 private NumberFormat numberFormat = NumberFormat.getInstance();
49
50 private List<File> reportsDirectories;
51
52 private final List<ReportTestSuite> testSuites = new ArrayList<ReportTestSuite>();
53
54 private static final int PCENT = 100;
55
56 public SurefireReportParser()
57 {
58 }
59
60 public SurefireReportParser( List<File> reportsDirectoriesFiles, Locale locale )
61 {
62 this.reportsDirectories = reportsDirectoriesFiles;
63
64 setLocale( locale );
65 }
66
67 public List<ReportTestSuite> parseXMLReportFiles()
68 throws MavenReportException
69 {
70 List<File> xmlReportFileList = new ArrayList<File>();
71 for ( File reportsDirectory : reportsDirectories )
72 {
73 if ( !reportsDirectory.exists() )
74 {
75 continue;
76 }
77 String[] xmlReportFiles = getIncludedFiles( reportsDirectory, INCLUDES, EXCLUDES );
78 for ( String xmlReportFile : xmlReportFiles )
79 {
80 File xmlReport = new File( reportsDirectory, xmlReportFile );
81 xmlReportFileList.add( xmlReport );
82 }
83 }
84 TestSuiteXmlParser parser = new TestSuiteXmlParser();
85 for ( File aXmlReportFileList : xmlReportFileList )
86 {
87 List<ReportTestSuite> suites;
88
89 try
90 {
91 suites = parser.parse( aXmlReportFileList.getAbsolutePath() );
92 }
93 catch ( ParserConfigurationException e )
94 {
95 throw new MavenReportException( "Error setting up parser for JUnit XML report", e );
96 }
97 catch ( SAXException e )
98 {
99 throw new MavenReportException( "Error parsing JUnit XML report " + aXmlReportFileList, e );
100 }
101 catch ( IOException e )
102 {
103 throw new MavenReportException( "Error reading JUnit XML report " + aXmlReportFileList, e );
104 }
105
106 testSuites.addAll( suites );
107 }
108
109 return testSuites;
110 }
111
112 protected String parseTestSuiteName( String lineString )
113 {
114 return lineString.substring( lineString.lastIndexOf( "." ) + 1, lineString.length() );
115 }
116
117 protected String parseTestSuitePackageName( String lineString )
118 {
119 return lineString.substring( lineString.indexOf( ":" ) + 2, lineString.lastIndexOf( "." ) );
120 }
121
122 protected String parseTestCaseName( String lineString )
123 {
124 return lineString.substring( 0, lineString.indexOf( "(" ) );
125 }
126
127 public Map<String, String> getSummary( List<ReportTestSuite> suites )
128 {
129 Map<String, String> totalSummary = new HashMap<String, String>();
130
131 int totalNumberOfTests = 0;
132
133 int totalNumberOfErrors = 0;
134
135 int totalNumberOfFailures = 0;
136
137 int totalNumberOfSkipped = 0;
138
139 float totalElapsedTime = 0.0f;
140
141 for ( ReportTestSuite suite : suites )
142 {
143 totalNumberOfTests += suite.getNumberOfTests();
144
145 totalNumberOfErrors += suite.getNumberOfErrors();
146
147 totalNumberOfFailures += suite.getNumberOfFailures();
148
149 totalNumberOfSkipped += suite.getNumberOfSkipped();
150
151 totalElapsedTime += suite.getTimeElapsed();
152 }
153
154 String totalPercentage =
155 computePercentage( totalNumberOfTests, totalNumberOfErrors, totalNumberOfFailures, totalNumberOfSkipped );
156
157 totalSummary.put( "totalTests", Integer.toString( totalNumberOfTests ) );
158
159 totalSummary.put( "totalErrors", Integer.toString( totalNumberOfErrors ) );
160
161 totalSummary.put( "totalFailures", Integer.toString( totalNumberOfFailures ) );
162
163 totalSummary.put( "totalSkipped", Integer.toString( totalNumberOfSkipped ) );
164
165 totalSummary.put( "totalElapsedTime", numberFormat.format( totalElapsedTime ) );
166
167 totalSummary.put( "totalPercentage", totalPercentage );
168
169 return totalSummary;
170 }
171
172 public void setReportsDirectory( File reportsDirectory )
173 {
174 this.reportsDirectories = Collections.singletonList( reportsDirectory );
175 }
176
177 public final void setLocale( Locale locale )
178 {
179 numberFormat = NumberFormat.getInstance( locale );
180 }
181
182 public NumberFormat getNumberFormat()
183 {
184 return this.numberFormat;
185 }
186
187 public Map<String, List<ReportTestSuite>> getSuitesGroupByPackage( List<ReportTestSuite> testSuitesList )
188 {
189 Map<String, List<ReportTestSuite>> suitePackage = new HashMap<String, List<ReportTestSuite>>();
190
191 for ( ReportTestSuite suite : testSuitesList )
192 {
193 List<ReportTestSuite> suiteList = new ArrayList<ReportTestSuite>();
194
195 if ( suitePackage.get( suite.getPackageName() ) != null )
196 {
197 suiteList = suitePackage.get( suite.getPackageName() );
198 }
199
200 suiteList.add( suite );
201
202 suitePackage.put( suite.getPackageName(), suiteList );
203 }
204
205 return suitePackage;
206 }
207
208 public String computePercentage( int tests, int errors, int failures, int skipped )
209 {
210 float percentage;
211 if ( tests == 0 )
212 {
213 percentage = 0;
214 }
215 else
216 {
217 percentage = ( (float) ( tests - errors - failures - skipped ) / (float) tests ) * PCENT;
218 }
219
220 return numberFormat.format( percentage );
221 }
222
223 public List<ReportTestCase> getFailureDetails( List<ReportTestSuite> testSuitesList )
224 {
225 List<ReportTestCase> failureDetailList = new ArrayList<ReportTestCase>();
226
227 for ( ReportTestSuite suite : testSuitesList )
228 {
229 List<ReportTestCase> testCaseList = suite.getTestCases();
230
231 if ( testCaseList != null )
232 {
233 for ( ReportTestCase tCase : testCaseList )
234 {
235
236 if ( tCase.getFailure() != null )
237 {
238 failureDetailList.add( tCase );
239 }
240 }
241 }
242 }
243
244 return failureDetailList;
245 }
246
247
248
249
250
251
252
253 public static boolean hasReportFiles( File directory )
254 {
255 return directory != null && directory.isDirectory()
256 && getIncludedFiles( directory, INCLUDES, EXCLUDES ).length > 0;
257 }
258
259 private static String[] getIncludedFiles( File directory, String includes, String excludes )
260 {
261 DirectoryScanner scanner = new DirectoryScanner();
262
263 scanner.setBasedir( directory );
264
265 scanner.setIncludes( StringUtils.split( includes, "," ) );
266
267 scanner.setExcludes( StringUtils.split( excludes, "," ) );
268
269 scanner.scan();
270
271 return scanner.getIncludedFiles();
272 }
273 }