1
package org.apache.maven.surefire.junit;
4
* Licensed to the Apache Software Foundation (ASF) under one
5
* or more contributor license agreements. See the NOTICE file
6
* distributed with this work for additional information
7
* regarding copyright ownership. The ASF licenses this file
8
* to you under the Apache License, Version 2.0 (the
9
* "License"); you may not use this file except in compliance
10
* with the License. You may obtain a copy of the License at
12
* http://www.apache.org/licenses/LICENSE-2.0
14
* Unless required by applicable law or agreed to in writing,
15
* software distributed under the License is distributed on an
16
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17
* KIND, either express or implied. See the License for the
18
* specific language governing permissions and limitations
22
import org.apache.maven.surefire.report.ReporterManager;
23
import org.apache.maven.surefire.testset.AbstractTestSet;
24
import org.apache.maven.surefire.testset.TestSetFailedException;
26
import java.lang.reflect.Constructor;
27
import java.lang.reflect.InvocationTargetException;
28
import java.lang.reflect.Method;
29
import java.lang.reflect.Modifier;
30
import java.lang.reflect.Proxy;
32
public final class JUnitTestSet
33
extends AbstractTestSet
35
public static final String TEST_CASE = "junit.framework.Test";
37
public static final String TEST_RESULT = "junit.framework.TestResult";
39
public static final String TEST_LISTENER = "junit.framework.TestListener";
41
public static final String TEST = "junit.framework.Test";
43
public static final String ADD_LISTENER_METHOD = "addListener";
45
public static final String RUN_METHOD = "run";
47
public static final String COUNT_TEST_CASES_METHOD = "countTestCases";
49
public static final String SETUP_METHOD = "setUp";
51
public static final String TEARDOWN_METHOD = "tearDown";
53
private static final String TEST_SUITE = "junit.framework.TestSuite";
55
private Class[] interfacesImplementedByDynamicProxy;
57
private Class testResultClass;
59
private Method addListenerMethod;
61
private Method countTestCasesMethod;
63
private Method runMethod;
65
private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
67
private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
69
public JUnitTestSet( Class testClass )
70
throws TestSetFailedException
77
private void processTestClass()
78
throws TestSetFailedException
82
Class testClass = getTestClass();
83
ClassLoader loader = testClass.getClassLoader();
85
testResultClass = loader.loadClass( TEST_RESULT );
87
Class testListenerInterface = loader.loadClass( TEST_LISTENER );
89
Class testInterface = loader.loadClass( TEST );
91
// ----------------------------------------------------------------------
92
// Strategy for executing JUnit tests
94
// o look for the suite method and if that is present execute that method
95
// to get the test object.
97
// o look for test classes that are assignable from TestCase
99
// o look for test classes that only implement the Test interface
100
// ----------------------------------------------------------------------
102
interfacesImplementedByDynamicProxy = new Class[1];
104
interfacesImplementedByDynamicProxy[0] = testListenerInterface;
106
// The interface implemented by the dynamic proxy (TestListener), happens to be
107
// the same as the param types of TestResult.addTestListener
108
Class[] addListenerParamTypes = interfacesImplementedByDynamicProxy;
110
addListenerMethod = testResultClass.getMethod( ADD_LISTENER_METHOD, addListenerParamTypes );
112
if ( testInterface.isAssignableFrom( testClass ) )//testObject.getClass() ) )
114
countTestCasesMethod = testInterface.getMethod( COUNT_TEST_CASES_METHOD, EMPTY_CLASS_ARRAY );
116
runMethod = testInterface.getMethod( RUN_METHOD, new Class[]{testResultClass} );
121
countTestCasesMethod = testClass.getMethod( COUNT_TEST_CASES_METHOD, EMPTY_CLASS_ARRAY );
123
runMethod = testClass.getMethod( RUN_METHOD, new Class[]{testResultClass} );
126
catch ( ClassNotFoundException e )
128
throw new TestSetFailedException( "JUnit classes not available", e );
130
catch ( NoSuchMethodException e )
132
throw new TestSetFailedException( "Class is not a JUnit TestCase", e );
136
private static Object constructTestObject( Class testClass )
137
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstantiationException,
138
ClassNotFoundException
140
Object testObject = createInstanceFromSuiteMethod( testClass );
142
if ( testObject == null && testClass.getClassLoader().loadClass( TEST_CASE ).isAssignableFrom( testClass ) )
144
Class[] constructorParamTypes = {Class.class};
146
Constructor constructor =
147
testClass.getClassLoader().loadClass( TEST_SUITE ).getConstructor( constructorParamTypes );
149
Object[] constructorParams = {testClass};
151
testObject = constructor.newInstance( constructorParams );
154
if ( testObject == null )
156
Constructor testConstructor = getTestConstructor( testClass );
158
if ( testConstructor.getParameterTypes().length == 0 )
160
testObject = testConstructor.newInstance( EMPTY_OBJECT_ARRAY );
164
testObject = testConstructor.newInstance( new Object[]{testClass.getName()} );
170
private static Object createInstanceFromSuiteMethod( Class testClass )
171
throws IllegalAccessException, InvocationTargetException
173
Object testObject = null;
176
Method suiteMethod = testClass.getMethod( "suite", EMPTY_CLASS_ARRAY );
178
if ( Modifier.isPublic( suiteMethod.getModifiers() ) && Modifier.isStatic( suiteMethod.getModifiers() ) )
180
testObject = suiteMethod.invoke( null, EMPTY_CLASS_ARRAY );
183
catch ( NoSuchMethodException e )
190
public void execute( ReporterManager reportManager, ClassLoader loader )
191
throws TestSetFailedException
193
Class testClass = getTestClass();
197
Object testObject = constructTestObject( testClass );
199
Object instanceOfTestResult = testResultClass.newInstance();
201
TestListenerInvocationHandler invocationHandler =
202
new TestListenerInvocationHandler( reportManager, instanceOfTestResult, loader );
204
Object testListener =
205
Proxy.newProxyInstance( loader, interfacesImplementedByDynamicProxy, invocationHandler );
207
Object[] addTestListenerParams = {testListener};
209
addListenerMethod.invoke( instanceOfTestResult, addTestListenerParams );
211
Object[] runParams = {instanceOfTestResult};
213
runMethod.invoke( testObject, runParams );
215
catch ( IllegalArgumentException e )
217
throw new TestSetFailedException( testClass.getName(), e );
219
catch ( InstantiationException e )
221
throw new TestSetFailedException( testClass.getName(), e );
223
catch ( IllegalAccessException e )
225
throw new TestSetFailedException( testClass.getName(), e );
227
catch ( InvocationTargetException e )
229
throw new TestSetFailedException( testClass.getName(), e.getTargetException() );
231
catch ( ClassNotFoundException e )
233
throw new TestSetFailedException( "JUnit classes not available", e );
235
catch ( NoSuchMethodException e )
237
throw new TestSetFailedException( "Class is not a JUnit TestCase", e );
241
private static Constructor getTestConstructor( Class testClass )
242
throws NoSuchMethodException
244
Constructor constructor;
247
constructor = testClass.getConstructor( new Class[]{String.class} );
249
catch ( NoSuchMethodException e )
251
constructor = testClass.getConstructor( EMPTY_CLASS_ARRAY );