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
29 import org.apache.maven.artifact.versioning.ArtifactVersion;
30 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
31 import org.apache.maven.artifact.versioning.VersionRange;
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.TestNGMapConfigurator;
37 import org.apache.maven.surefire.testset.TestSetFailedException;
38 import org.apache.maven.surefire.util.NestedRuntimeException;
39 import org.apache.maven.surefire.util.internal.StringUtils;
40 import org.testng.TestNG;
41
42
43
44
45
46
47
48 public class TestNGExecutor
49 {
50
51
52 private TestNGExecutor()
53 {
54
55 }
56
57 public static void run( Class[] testClasses, String testSourceDirectory, Map options, ArtifactVersion version,
58 RunListener reportManager, TestNgTestSuite suite, File reportsDirectory, final String methodNamePattern )
59 throws TestSetFailedException
60 {
61 TestNG testng = new TestNG( true );
62 if (!StringUtils.isBlank( methodNamePattern ))
63 {
64 applyMethodNameFiltering( testng, methodNamePattern );
65 }
66 Configurator configurator = getConfigurator( version );
67 configurator.configure( testng, options );
68 postConfigure( testng, testSourceDirectory, reportManager, suite, reportsDirectory );
69 testng.setTestClasses( testClasses );
70 testng.run();
71 }
72
73 private static void applyMethodNameFiltering(TestNG testng, String methodNamePattern)
74 throws TestSetFailedException
75 {
76
77 String clazzName = "org.apache.maven.surefire.testng.utils.MethodSelector";
78
79 testng.addMethodSelector( clazzName , 10000 );
80 try
81 {
82 Class clazz = Class.forName( clazzName );
83
84 Method method = clazz.getMethod( "setMethodName", new Class[]{String.class} );
85 method.invoke( null, new Object[]{methodNamePattern} );
86 }
87 catch ( ClassNotFoundException e )
88 {
89 throw new TestSetFailedException(e.getMessage(), e);
90 }
91 catch ( SecurityException e )
92 {
93 throw new TestSetFailedException(e.getMessage(), e);
94 }
95 catch ( NoSuchMethodException e )
96 {
97 throw new TestSetFailedException(e.getMessage(), e);
98 }
99 catch ( IllegalArgumentException e )
100 {
101 throw new TestSetFailedException(e.getMessage(), e);
102 }
103 catch ( IllegalAccessException e )
104 {
105 throw new TestSetFailedException(e.getMessage(), e);
106 }
107 catch ( InvocationTargetException e )
108 {
109 throw new TestSetFailedException(e.getMessage(), e);
110 }
111 }
112
113 public static void run( List suiteFiles, String testSourceDirectory, Map options, ArtifactVersion version,
114 RunListener reportManager, TestNgTestSuite suite, File reportsDirectory )
115 throws TestSetFailedException
116 {
117 TestNG testng = new TestNG( true );
118 Configurator configurator = getConfigurator( version );
119 configurator.configure( testng, options );
120 postConfigure( testng, testSourceDirectory, reportManager, suite, reportsDirectory );
121 testng.setTestSuites( suiteFiles );
122 testng.run();
123 }
124
125 private static Configurator getConfigurator( ArtifactVersion version )
126 throws TestSetFailedException
127 {
128 try
129 {
130 VersionRange range = VersionRange.createFromVersionSpec( "[4.7,5.1]" );
131 if ( range.containsVersion( version ) )
132 {
133 return new TestNG4751Configurator();
134 }
135 range = VersionRange.createFromVersionSpec( "[5.2]" );
136 if ( range.containsVersion( version ) )
137 {
138 return new TestNG52Configurator();
139 }
140 range = VersionRange.createFromVersionSpec( "[5.3,)" );
141 if ( range.containsVersion( version ) )
142 {
143 return new TestNGMapConfigurator();
144 }
145
146 throw new TestSetFailedException( "Unknown TestNG version " + version );
147 }
148 catch ( InvalidVersionSpecificationException invsex )
149 {
150 throw new TestSetFailedException( "Bug in plugin. Please report it with the attached stacktrace", invsex );
151 }
152 }
153
154
155 private static void postConfigure( TestNG testNG, String sourcePath, RunListener reportManager, TestNgTestSuite suite,
156 File reportsDirectory )
157 throws TestSetFailedException
158 {
159
160 testNG.setVerbose( 0 );
161
162 TestNGReporter reporter = createTestNGReporter( reportManager, suite );
163 testNG.addListener( (Object) reporter );
164
165
166 if ( sourcePath != null )
167 {
168 testNG.setSourcePath( sourcePath );
169 }
170
171 testNG.setOutputDirectory( reportsDirectory.getAbsolutePath() );
172 }
173
174
175
176 private static TestNGReporter createTestNGReporter( RunListener reportManager, TestNgTestSuite suite )
177 {
178 try
179 {
180 Class.forName( "org.testng.internal.IResultListener" );
181 Class c = Class.forName( "org.apache.maven.surefire.testng.ConfigurationAwareTestNGReporter" );
182 try
183 {
184 Constructor ctor = c.getConstructor( new Class[]{ RunListener.class, TestNgTestSuite.class } );
185 return (TestNGReporter) ctor.newInstance( new Object[]{ reportManager, suite } );
186 }
187 catch ( Exception e )
188 {
189 throw new NestedRuntimeException( "Bug in ConfigurationAwareTestNGReporter", e );
190 }
191 }
192 catch ( ClassNotFoundException e )
193 {
194 return new TestNGReporter( reportManager );
195 }
196 }
197
198 }