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