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