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