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