View Javadoc

1   package org.apache.maven.plugins.surefire.report;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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.ListIterator;
31  import java.util.Locale;
32  import java.util.Map;
33  
34  import javax.xml.parsers.ParserConfigurationException;
35  
36  import org.apache.maven.reporting.MavenReportException;
37  import org.codehaus.plexus.util.DirectoryScanner;
38  import org.codehaus.plexus.util.StringUtils;
39  import org.xml.sax.SAXException;
40  
41  /**
42   * @version $Id: SurefireReportParser.java 1204901 2011-11-22 10:35:17Z stephenc $
43   */
44  public class SurefireReportParser
45  {
46      private static final String INCLUDES = "*.xml";
47  
48      private static final String EXCLUDES = "*.txt, testng-failed.xml, testng-failures.xml, testng-results.xml";
49  
50      private NumberFormat numberFormat = NumberFormat.getInstance();
51  
52      private List reportsDirectories;
53  
54      private final List testSuites = new ArrayList();
55  
56      private static final int PCENT = 100;
57  
58      public SurefireReportParser()
59      {
60      }
61  
62      public SurefireReportParser( List reportsDirectoriesFiles , Locale locale )
63      {
64          this.reportsDirectories = reportsDirectoriesFiles;
65  
66          setLocale( locale );
67      }
68  
69      public List parseXMLReportFiles()
70          throws MavenReportException
71      {
72          List xmlReportFileList = new ArrayList();
73          for ( int i = 0; i < reportsDirectories.size(); i++ )
74          {
75              File reportsDirectory = (File) reportsDirectories.get( i );
76              if ( !reportsDirectory.exists() )
77              {
78                  continue;
79              }
80              String[] xmlReportFiles =
81                  getIncludedFiles( reportsDirectory, INCLUDES, EXCLUDES );
82              for ( int j = 0; j < xmlReportFiles.length; j++ )
83              {
84                  File xmlReport = new File( reportsDirectory, xmlReportFiles[j] );
85                  xmlReportFileList.add( xmlReport );
86              }
87          }
88          TestSuiteXmlParser parser = new TestSuiteXmlParser();
89          for ( int index = 0; index < xmlReportFileList.size(); index++ )
90          {
91              Collection suites;
92  
93              File currentReport = (File) xmlReportFileList.get( index );
94  
95              try
96              {
97                  suites = parser.parse( currentReport.getAbsolutePath() );
98              }
99              catch ( ParserConfigurationException e )
100             {
101                 throw new MavenReportException( "Error setting up parser for JUnit XML report", e );
102             }
103             catch ( SAXException e )
104             {
105                 throw new MavenReportException( "Error parsing JUnit XML report " + currentReport, e );
106             }
107             catch ( IOException e )
108             {
109                 throw new MavenReportException( "Error reading JUnit XML report " + currentReport, e );
110             }
111 
112             testSuites.addAll( suites );
113         }
114 
115         return testSuites;
116     }
117 
118     protected String parseTestSuiteName( String lineString )
119     {
120         return lineString.substring( lineString.lastIndexOf( "." ) + 1, lineString.length() );
121     }
122 
123     protected String parseTestSuitePackageName( String lineString )
124     {
125         return lineString.substring( lineString.indexOf( ":" ) + 2, lineString.lastIndexOf( "." ) );
126     }
127 
128     protected String parseTestCaseName( String lineString )
129     {
130         return lineString.substring( 0, lineString.indexOf( "(" ) );
131     }
132 
133     public Map getSummary( List suites )
134     {
135         Map totalSummary = new HashMap();
136 
137         ListIterator iter = suites.listIterator();
138 
139         int totalNumberOfTests = 0;
140 
141         int totalNumberOfErrors = 0;
142 
143         int totalNumberOfFailures = 0;
144 
145         int totalNumberOfSkipped = 0;
146 
147         float totalElapsedTime = 0.0f;
148 
149         while ( iter.hasNext() )
150         {
151             ReportTestSuite suite = (ReportTestSuite) iter.next();
152 
153             totalNumberOfTests += suite.getNumberOfTests();
154 
155             totalNumberOfErrors += suite.getNumberOfErrors();
156 
157             totalNumberOfFailures += suite.getNumberOfFailures();
158 
159             totalNumberOfSkipped += suite.getNumberOfSkipped();
160 
161             totalElapsedTime += suite.getTimeElapsed();
162         }
163 
164         String totalPercentage =
165             computePercentage( totalNumberOfTests, totalNumberOfErrors, totalNumberOfFailures, totalNumberOfSkipped );
166 
167         totalSummary.put( "totalTests", Integer.toString( totalNumberOfTests ) );
168 
169         totalSummary.put( "totalErrors", Integer.toString( totalNumberOfErrors ) );
170 
171         totalSummary.put( "totalFailures", Integer.toString( totalNumberOfFailures ) );
172 
173         totalSummary.put( "totalSkipped", Integer.toString( totalNumberOfSkipped ) );
174 
175         totalSummary.put( "totalElapsedTime", numberFormat.format( totalElapsedTime ) );
176 
177         totalSummary.put( "totalPercentage", totalPercentage );
178 
179         return totalSummary;
180     }
181 
182     public void setReportsDirectory( File reportsDirectory )
183     {
184         this.reportsDirectories = Collections.singletonList( reportsDirectory );
185     }
186 
187     public final void setLocale( Locale locale )
188     {
189         numberFormat = NumberFormat.getInstance( locale );
190     }
191 
192     public NumberFormat getNumberFormat()
193     {
194         return this.numberFormat;
195     }
196 
197     public Map getSuitesGroupByPackage( List testSuitesList )
198     {
199         ListIterator iter = testSuitesList.listIterator();
200 
201         Map suitePackage = new HashMap();
202 
203         while ( iter.hasNext() )
204         {
205             ReportTestSuite suite = (ReportTestSuite) iter.next();
206 
207             List suiteList = new ArrayList();
208 
209             if ( suitePackage.get( suite.getPackageName() ) != null )
210             {
211                 suiteList = (List) suitePackage.get( suite.getPackageName() );
212             }
213 
214             suiteList.add( suite );
215 
216             suitePackage.put( suite.getPackageName(), suiteList );
217         }
218 
219         return suitePackage;
220     }
221 
222     public String computePercentage( int tests, int errors, int failures, int skipped )
223     {
224         float percentage;
225         if ( tests == 0 )
226         {
227             percentage = 0;
228         }
229         else
230         {
231             percentage = ( (float) ( tests - errors - failures - skipped ) / (float) tests ) * PCENT;
232         }
233 
234         return numberFormat.format( percentage );
235     }
236 
237     public List getFailureDetails( List testSuitesList )
238     {
239         ListIterator iter = testSuitesList.listIterator();
240 
241         List failureDetailList = new ArrayList();
242 
243         while ( iter.hasNext() )
244         {
245             ReportTestSuite suite = (ReportTestSuite) iter.next();
246 
247             List testCaseList = suite.getTestCases();
248 
249             if ( testCaseList != null )
250             {
251                 ListIterator caseIter = testCaseList.listIterator();
252 
253                 while ( caseIter.hasNext() )
254                 {
255                     ReportTestCase tCase = (ReportTestCase) caseIter.next();
256 
257                     if ( tCase.getFailure() != null )
258                     {
259                         failureDetailList.add( tCase );
260                     }
261                 }
262             }
263         }
264 
265         return failureDetailList;
266     }
267 
268     /**
269      * Returns {@code true} if the specified directory contains at least one report file.
270      *
271      * @param directory the directory
272      * @return {@code true} if the specified directory contains at least one report file.
273      */
274     public static boolean hasReportFiles( File directory )
275     {
276         return directory != null && directory.isDirectory()
277             && getIncludedFiles( directory, INCLUDES, EXCLUDES ).length > 0;
278     }
279 
280     private static String[] getIncludedFiles( File directory, String includes, String excludes )
281     {
282         DirectoryScanner scanner = new DirectoryScanner();
283 
284         scanner.setBasedir( directory );
285 
286         scanner.setIncludes( StringUtils.split( includes, "," ) );
287 
288         scanner.setExcludes( StringUtils.split( excludes, "," ) );
289 
290         scanner.scan();
291 
292         return scanner.getIncludedFiles();
293     }
294 }