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