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