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.surefire.booter.ProviderParameterNames;
23 import org.apache.maven.surefire.report.RunListener;
24 import org.apache.maven.surefire.testng.conf.Configurator;
25 import org.apache.maven.surefire.testset.TestSetFailedException;
26 import org.apache.maven.surefire.util.NestedRuntimeException;
27 import org.apache.maven.surefire.util.internal.StringUtils;
28 import org.testng.TestNG;
29 import org.testng.xml.XmlClass;
30 import org.testng.xml.XmlMethodSelector;
31 import org.testng.xml.XmlSuite;
32 import org.testng.xml.XmlTest;
33
34 import java.io.File;
35 import java.lang.reflect.Constructor;
36 import java.lang.reflect.InvocationTargetException;
37 import java.lang.reflect.Method;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.List;
41 import java.util.Map;
42
43
44
45
46
47
48
49 public class TestNGExecutor
50 {
51
52 private TestNGExecutor()
53 {
54
55 }
56
57 public static void run( Class[] testClasses, String testSourceDirectory, Map options, RunListener reportManager,
58 TestNgTestSuite suite, File reportsDirectory, final String methodNamePattern )
59 throws TestSetFailedException
60 {
61 TestNG testng = new TestNG( true );
62
63 Configurator configurator = getConfigurator( (String) options.get( "testng.configurator" ) );
64 System.out.println( "Configuring TestNG with: " + configurator.getClass().getSimpleName() );
65
66 XmlMethodSelector groupMatchingSelector = getGroupMatchingSelector( options );
67 XmlMethodSelector methodNameFilteringSelector = getMethodNameFilteringSelector( methodNamePattern );
68
69 List<XmlSuite> suites = new ArrayList<XmlSuite>( testClasses.length );
70 for ( Class testClass : testClasses )
71 {
72 XmlSuite xmlSuite = new XmlSuite();
73
74 xmlSuite.setName( testClass.getName() );
75 configurator.configure( xmlSuite, options );
76
77 XmlTest xmlTest = new XmlTest( xmlSuite );
78 xmlTest.setXmlClasses( Arrays.asList( new XmlClass( testClass ) ) );
79
80 addSelector( xmlTest, groupMatchingSelector );
81 addSelector( xmlTest, methodNameFilteringSelector );
82
83 suites.add( xmlSuite );
84 }
85
86 testng.setXmlSuites( suites );
87
88 configurator.configure( testng, options );
89 postConfigure( testng, testSourceDirectory, reportManager, suite, reportsDirectory );
90
91 testng.run();
92 }
93
94 private static void addSelector( XmlTest xmlTest, XmlMethodSelector selector )
95 {
96 if ( selector != null )
97 {
98 xmlTest.getMethodSelectors().add( selector );
99 }
100 }
101
102 private static XmlMethodSelector getMethodNameFilteringSelector( String methodNamePattern )
103 throws TestSetFailedException
104 {
105 if ( StringUtils.isBlank( methodNamePattern ) )
106 {
107 return null;
108 }
109
110
111 String clazzName = "org.apache.maven.surefire.testng.utils.MethodSelector";
112 try
113 {
114 Class clazz = Class.forName( clazzName );
115
116 Method method = clazz.getMethod( "setMethodName", new Class[] { String.class } );
117 method.invoke( null, methodNamePattern );
118 }
119 catch ( ClassNotFoundException e )
120 {
121 throw new TestSetFailedException( e.getMessage(), e );
122 }
123 catch ( SecurityException e )
124 {
125 throw new TestSetFailedException( e.getMessage(), e );
126 }
127 catch ( NoSuchMethodException e )
128 {
129 throw new TestSetFailedException( e.getMessage(), e );
130 }
131 catch ( IllegalArgumentException e )
132 {
133 throw new TestSetFailedException( e.getMessage(), e );
134 }
135 catch ( IllegalAccessException e )
136 {
137 throw new TestSetFailedException( e.getMessage(), e );
138 }
139 catch ( InvocationTargetException e )
140 {
141 throw new TestSetFailedException( e.getMessage(), e );
142 }
143
144 XmlMethodSelector xms = new XmlMethodSelector();
145
146 xms.setName( clazzName );
147
148 xms.setPriority( 10000 );
149
150 return xms;
151 }
152
153 private static XmlMethodSelector getGroupMatchingSelector( Map options )
154 throws TestSetFailedException
155 {
156 String groups = (String) options.get( ProviderParameterNames.TESTNG_GROUPS_PROP );
157 String excludedGroups = (String) options.get( ProviderParameterNames.TESTNG_EXCLUDEDGROUPS_PROP );
158
159 if ( groups == null && excludedGroups == null )
160 {
161 return null;
162 }
163
164
165 String clazzName = "org.apache.maven.surefire.testng.utils.GroupMatcherMethodSelector";
166 try
167 {
168 Class clazz = Class.forName( clazzName );
169
170
171 Method method = clazz.getMethod( "setGroups", new Class[] { String.class, String.class } );
172 method.invoke( null, groups, excludedGroups );
173 }
174 catch ( ClassNotFoundException e )
175 {
176 throw new TestSetFailedException( e.getMessage(), e );
177 }
178 catch ( SecurityException e )
179 {
180 throw new TestSetFailedException( e.getMessage(), e );
181 }
182 catch ( NoSuchMethodException e )
183 {
184 throw new TestSetFailedException( e.getMessage(), e );
185 }
186 catch ( IllegalArgumentException e )
187 {
188 throw new TestSetFailedException( e.getMessage(), e );
189 }
190 catch ( IllegalAccessException e )
191 {
192 throw new TestSetFailedException( e.getMessage(), e );
193 }
194 catch ( InvocationTargetException e )
195 {
196 throw new TestSetFailedException( e.getMessage(), e );
197 }
198
199 XmlMethodSelector xms = new XmlMethodSelector();
200
201 xms.setName( clazzName );
202
203 xms.setPriority( 9999 );
204
205 return xms;
206 }
207
208 public static void run( List<String> suiteFiles, String testSourceDirectory, Map options,
209 RunListener reportManager, TestNgTestSuite suite, File reportsDirectory )
210 throws TestSetFailedException
211 {
212 TestNG testng = new TestNG( true );
213 Configurator configurator = getConfigurator( (String) options.get( "testng.configurator" ) );
214 configurator.configure( testng, options );
215 postConfigure( testng, testSourceDirectory, reportManager, suite, reportsDirectory );
216 testng.setTestSuites( suiteFiles );
217 testng.run();
218 }
219
220 private static Configurator getConfigurator( String className )
221 {
222 try
223 {
224 return (Configurator) Class.forName( className ).newInstance();
225 }
226 catch ( InstantiationException e )
227 {
228 throw new RuntimeException( e );
229 }
230 catch ( IllegalAccessException e )
231 {
232 throw new RuntimeException( e );
233 }
234 catch ( ClassNotFoundException e )
235 {
236 throw new RuntimeException( e );
237 }
238 }
239
240 private static void postConfigure( TestNG testNG, String sourcePath, RunListener reportManager,
241 TestNgTestSuite suite, File reportsDirectory )
242 throws TestSetFailedException
243 {
244
245 testNG.setVerbose( 0 );
246
247 TestNGReporter reporter = createTestNGReporter( reportManager, suite );
248 testNG.addListener( (Object) reporter );
249
250
251 if ( sourcePath != null )
252 {
253 testNG.setSourcePath( sourcePath );
254 }
255
256 testNG.setOutputDirectory( reportsDirectory.getAbsolutePath() );
257 }
258
259
260
261 private static TestNGReporter createTestNGReporter( RunListener reportManager, TestNgTestSuite suite )
262 {
263 try
264 {
265 Class.forName( "org.testng.internal.IResultListener" );
266 Class c = Class.forName( "org.apache.maven.surefire.testng.ConfigurationAwareTestNGReporter" );
267 try
268 {
269 Constructor ctor = c.getConstructor( new Class[] { RunListener.class, TestNgTestSuite.class } );
270 return (TestNGReporter) ctor.newInstance( reportManager, suite );
271 }
272 catch ( Exception e )
273 {
274 throw new NestedRuntimeException( "Bug in ConfigurationAwareTestNGReporter", e );
275 }
276 }
277 catch ( ClassNotFoundException e )
278 {
279 return new TestNGReporter( reportManager );
280 }
281 }
282
283 }