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