View Javadoc
1   package org.apache.maven.surefire.testng;
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.util.ResourceBundle;
23  import org.apache.maven.surefire.report.CategorizedReportEntry;
24  import org.apache.maven.surefire.report.PojoStackTraceWriter;
25  import org.apache.maven.surefire.report.ReportEntry;
26  import org.apache.maven.surefire.report.RunListener;
27  import org.apache.maven.surefire.report.SimpleReportEntry;
28  
29  import org.testng.ISuite;
30  import org.testng.ISuiteListener;
31  import org.testng.ITestContext;
32  import org.testng.ITestListener;
33  import org.testng.ITestResult;
34  
35  /**
36   * Listens for and provides and adaptor layer so that
37   * TestNG tests can report their status to the current
38   * {@link org.apache.maven.surefire.report.RunListener}.
39   *
40   * @author jkuhnert
41   * @noinspection ThrowableResultOfMethodCallIgnored
42   */
43  public class TestNGReporter
44      implements ITestListener, ISuiteListener
45  {
46      public static final String SUREFIRE_BUNDLE_NAME = "org.apache.maven.surefire.surefire";
47  
48      private final ResourceBundle bundle = ResourceBundle.getBundle( SUREFIRE_BUNDLE_NAME );
49  
50      /**
51       * core Surefire reporting
52       */
53      private final RunListener reporter;
54  
55      /**
56       * Constructs a new instance that will listen to
57       * test updates from a {@link TestNG} class instance.
58       * <p/>
59       * <p/>It is assumed that the requisite {@link TestNG#addListener(ITestListener)}
60       * method call has already associated with this instance <i>before</i> the test
61       * suite is run.
62       *
63       * @param reportManager Instance to report suite status to
64       */
65      public TestNGReporter( RunListener reportManager )
66      {
67          this.reporter = reportManager;
68  
69          if ( reportManager == null )
70          {
71              throw new IllegalArgumentException( "ReportManager passed in was null." );
72          }
73  
74      }
75  
76      public void onTestStart( ITestResult result )
77      {
78          String rawString = bundle.getString( "testStarting" );
79          String group = groupString( result.getMethod().getGroups(), result.getTestClass().getName() );
80          ReportEntry report =
81              new CategorizedReportEntry( getSource( result ), getUserFriendlyTestName( result ), group );
82          reporter.testStarting( report );
83      }
84  
85      private String getSource( ITestResult result )
86      {
87          return result.getTestClass().getName();
88      }
89  
90      public void onTestSuccess( ITestResult result )
91      {
92          ReportEntry report = new SimpleReportEntry( getSource( result ), getUserFriendlyTestName( result ) );
93          reporter.testSucceeded( report );
94      }
95  
96      public void onTestFailure( ITestResult result )
97      {
98          ReportEntry report = SimpleReportEntry.withException( getSource( result ), getUserFriendlyTestName( result ),
99                                                                new PojoStackTraceWriter(
100                                                                   result.getTestClass().getRealClass().getName(),
101                                                                   result.getMethod().getMethodName(),
102                                                                   result.getThrowable() ) );
103 
104         reporter.testFailed( report );
105     }
106 
107     private static String getUserFriendlyTestName( ITestResult result )
108     {
109         // This is consistent with the JUnit output
110         return result.getName() + "(" + result.getTestClass().getName() + ")";
111     }
112 
113     public void onTestSkipped( ITestResult result )
114     {
115         ReportEntry report = new SimpleReportEntry( getSource( result ), getUserFriendlyTestName( result ) );
116 
117         reporter.testSkipped( report );
118     }
119 
120     public void onTestFailedButWithinSuccessPercentage( ITestResult result )
121     {
122         ReportEntry report = SimpleReportEntry.withException( getSource( result ), getUserFriendlyTestName( result ),
123                                                               new PojoStackTraceWriter(
124                                                                   result.getTestClass().getRealClass().getName(),
125                                                                   result.getMethod().getMethodName(),
126                                                                   result.getThrowable() ) );
127 
128         reporter.testSucceeded( report );
129     }
130 
131     public void onStart( ITestContext context )
132     {
133 
134     }
135 
136     public void onFinish( ITestContext context )
137     {
138 
139     }
140 
141 
142     public void onStart( ISuite suite )
143     {
144 
145     }
146 
147     public void onFinish( ISuite suite )
148     {
149 
150     }
151 
152     /**
153      * Creates a string out of the list of testng groups in the
154      * form of <pre>"group1,group2,group3"</pre>.
155      *
156      * @param groups       The groups being run
157      * @param defaultValue The default to use if no groups
158      * @return a string describing the groups
159      */
160     private static String groupString( String[] groups, String defaultValue )
161     {
162         String retVal;
163         if ( groups != null && groups.length > 0 )
164         {
165             StringBuilder str = new StringBuilder();
166             for ( int i = 0; i < groups.length; i++ )
167             {
168                 str.append( groups[i] );
169                 if ( i + 1 < groups.length )
170                 {
171                     str.append( "," );
172                 }
173             }
174             retVal = str.toString();
175         }
176         else
177         {
178             retVal = defaultValue;
179         }
180         return retVal;
181     }
182 
183     public void onConfigurationFailure( ITestResult result )
184     {
185         onTestFailure( result );
186     }
187 
188     public void onConfigurationSkip( ITestResult result )
189     {
190         onTestSkipped( result );
191     }
192 
193     public void onConfigurationSuccess( ITestResult result )
194     {
195         // DGF Don't record configuration successes as separate tests
196         //onTestSuccess( result );
197     }
198 
199 }