1 package org.apache.maven.surefire.testng;
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.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Properties;
30 import java.util.SortedMap;
31 import java.util.TreeMap;
32 import org.apache.maven.surefire.NonAbstractClassFilter;
33 import org.apache.maven.surefire.report.ConsoleOutputCapture;
34 import org.apache.maven.surefire.report.ConsoleOutputReceiver;
35 import org.apache.maven.surefire.report.ReportEntry;
36 import org.apache.maven.surefire.report.ReporterException;
37 import org.apache.maven.surefire.report.ReporterFactory;
38 import org.apache.maven.surefire.report.RunListener;
39 import org.apache.maven.surefire.report.SimpleReportEntry;
40 import org.apache.maven.surefire.testset.TestSetFailedException;
41 import org.apache.maven.surefire.util.RunOrderCalculator;
42 import org.apache.maven.surefire.util.ScanResult;
43 import org.apache.maven.surefire.util.TestsToRun;
44
45
46
47
48
49
50
51 public class TestNGDirectoryTestSuite
52 implements TestNgTestSuite
53 {
54
55 private final Map options;
56
57 private final Map junitOptions;
58
59 private final String testSourceDirectory;
60
61 private final File reportsDirectory;
62
63 private SortedMap<String, TestNGTestSet> testSets;
64
65 private final ScanResult scanResult;
66
67 private final String testMethodPattern;
68
69 private final RunOrderCalculator runOrderCalculator;
70
71 private final Class junitTestClass;
72
73 public TestNGDirectoryTestSuite( String testSourceDirectory, Properties confOptions, File reportsDirectory, String testMethodPattern,
74 RunOrderCalculator runOrderCalculator, ScanResult scanResult )
75 {
76
77 this.runOrderCalculator = runOrderCalculator;
78
79 this.options = confOptions;
80
81 this.testSourceDirectory = testSourceDirectory;
82 this.reportsDirectory = reportsDirectory;
83 this.scanResult = scanResult;
84 this.testMethodPattern = testMethodPattern;
85 this.junitTestClass = findJUnitTestClass();
86 this.junitOptions = createJUnitOptions();
87 }
88
89 public void execute( TestsToRun testsToRun, ReporterFactory reporterManagerFactory )
90 throws ReporterException, TestSetFailedException
91 {
92
93 if ( !testsToRun.allowEagerReading() )
94 {
95 executeLazy( testsToRun, reporterManagerFactory );
96 }
97 else if ( testsToRun.containsAtLeast( 2 ) )
98 {
99 executeMulti( testsToRun, reporterManagerFactory );
100 }
101 else if ( testsToRun.containsAtLeast( 1 ) )
102 {
103 Class testClass = testsToRun.iterator().next();
104 executeSingleClass( reporterManagerFactory, testClass );
105 }
106 }
107
108 private void executeSingleClass( ReporterFactory reporterManagerFactory, Class testClass )
109 throws TestSetFailedException
110 {
111 this.options.put( "suitename", testClass.getName() );
112
113 RunListener reporter = reporterManagerFactory.createReporter();
114 ConsoleOutputCapture.startCapture( (ConsoleOutputReceiver) reporter );
115
116 startTestSuite( reporter, this );
117
118 final Map optionsToUse = isJUnitTest( testClass ) ? junitOptions : options;
119
120 TestNGExecutor.run( new Class[]{ testClass }, testSourceDirectory, optionsToUse, reporter, this,
121 reportsDirectory, testMethodPattern );
122
123 finishTestSuite( reporter, this );
124 }
125
126 public void executeLazy( TestsToRun testsToRun, ReporterFactory reporterFactory )
127 throws ReporterException, TestSetFailedException
128 {
129
130 for ( Class c : testsToRun )
131 {
132 executeSingleClass( reporterFactory, c );
133 }
134 }
135
136 private Class findJUnitTestClass()
137 {
138 Class junitTest;
139 try
140 {
141 junitTest = Class.forName( "junit.framework.Test" );
142 }
143 catch ( ClassNotFoundException e )
144 {
145 junitTest = null;
146 }
147 return junitTest;
148 }
149
150 public void executeMulti( TestsToRun testsToRun, ReporterFactory reporterFactory )
151 throws ReporterException, TestSetFailedException
152 {
153 List<Class> testNgTestClasses = new ArrayList<Class>();
154 List<Class> junitTestClasses = new ArrayList<Class>();
155 for ( Class c : testsToRun )
156 {
157 if ( isJUnitTest( c ) )
158 {
159 junitTestClasses.add( c );
160 }
161 else
162 {
163 testNgTestClasses.add( c );
164 }
165 }
166
167 File testNgReportsDirectory = reportsDirectory, junitReportsDirectory = reportsDirectory;
168
169 if ( junitTestClasses.size() > 0 && testNgTestClasses.size() > 0 )
170 {
171 testNgReportsDirectory = new File( reportsDirectory, "testng-native-results" );
172 junitReportsDirectory = new File( reportsDirectory, "testng-junit-results" );
173 }
174
175 RunListener reporterManager = reporterFactory.createReporter();
176 ConsoleOutputCapture.startCapture( (ConsoleOutputReceiver) reporterManager );
177 startTestSuite( reporterManager, this );
178
179 Class[] testClasses = testNgTestClasses.toArray( new Class[testNgTestClasses.size()] );
180
181 TestNGExecutor.run( testClasses, this.testSourceDirectory, options, reporterManager, this,
182 testNgReportsDirectory, testMethodPattern );
183
184 if ( junitTestClasses.size() > 0 )
185 {
186 testClasses = junitTestClasses.toArray( new Class[junitTestClasses.size()] );
187
188 TestNGExecutor.run( testClasses, testSourceDirectory, junitOptions, reporterManager, this,
189 junitReportsDirectory, testMethodPattern );
190 }
191
192 finishTestSuite( reporterManager, this );
193 }
194
195 private boolean isJUnitTest( Class c )
196 {
197 return junitTestClass != null && junitTestClass.isAssignableFrom( c );
198 }
199
200 private Map createJUnitOptions()
201 {
202 Map junitOptions = new HashMap( this.options );
203 junitOptions.put( "junit", Boolean.TRUE );
204 return junitOptions;
205 }
206
207
208 public void execute( String testSetName, ReporterFactory reporterManagerFactory )
209 throws ReporterException, TestSetFailedException
210 {
211 if ( testSets == null )
212 {
213 throw new IllegalStateException( "You must call locateTestSets before calling execute" );
214 }
215 TestNGTestSet testSet = testSets.get( testSetName );
216
217 if ( testSet == null )
218 {
219 throw new TestSetFailedException( "Unable to find test set '" + testSetName + "' in suite" );
220 }
221
222 RunListener reporter = reporterManagerFactory.createReporter();
223 ConsoleOutputCapture.startCapture( (ConsoleOutputReceiver) reporter );
224
225 startTestSuite( reporter, this );
226
227 TestNGExecutor.run( new Class[]{ testSet.getTestClass() }, this.testSourceDirectory, this.options, reporter, this, reportsDirectory, testMethodPattern );
228
229 finishTestSuite( reporter, this );
230 }
231
232 public static void startTestSuite( RunListener reporter, Object suite )
233 {
234 ReportEntry report = new SimpleReportEntry( suite.getClass().getName(), getSuiteName( suite ) );
235
236 try
237 {
238 reporter.testSetStarting( report );
239 }
240 catch ( ReporterException e )
241 {
242
243 }
244 }
245
246 public static void finishTestSuite( RunListener reporterManager, Object suite )
247 throws ReporterException
248 {
249 ReportEntry report = new SimpleReportEntry( suite.getClass().getName(), getSuiteName( suite ) );
250
251 reporterManager.testSetCompleted( report );
252 }
253
254 public String getSuiteName()
255 {
256 String result = (String) options.get( "suitename" );
257 if ( result == null )
258 {
259 result = "TestSuite";
260 }
261 return result;
262 }
263
264 private static String getSuiteName( Object suite )
265 {
266 String result;
267 if ( suite instanceof TestNGDirectoryTestSuite )
268 {
269 return ( (TestNGDirectoryTestSuite) suite ).getSuiteName();
270 }
271 else if ( suite instanceof TestNGXmlTestSuite )
272 {
273 return ( (TestNGXmlTestSuite) suite ).getSuiteName();
274 }
275 else
276 {
277 result = "TestSuite";
278 }
279
280 return result;
281 }
282
283 public Map locateTestSets( ClassLoader classLoader )
284 throws TestSetFailedException
285 {
286 if ( testSets != null )
287 {
288 throw new IllegalStateException( "You can't call locateTestSets twice" );
289 }
290 testSets = new TreeMap<String, TestNGTestSet>();
291
292 final TestsToRun scanned = scanResult.applyFilter( new NonAbstractClassFilter(), classLoader );
293
294 final TestsToRun testsToRun = runOrderCalculator.orderTestClasses( scanned );
295
296 for ( Class testClass : testsToRun )
297 {
298 TestNGTestSet testSet = new TestNGTestSet( testClass );
299
300 if ( testSets.containsKey( testSet.getName() ) )
301 {
302 throw new TestSetFailedException( "Duplicate test set '" + testSet.getName() + "'" );
303 }
304 testSets.put( testSet.getName(), testSet );
305
306 }
307
308 return Collections.unmodifiableSortedMap( testSets );
309 }
310
311 }