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