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