blob: dcb975aaf02de8b9f4b4f86fa33ded2aa73e41f1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* David Saff (saff@mit.edu) - initial API and implementation
* (bug 102632: [JUnit] Support for JUnit 4.)
*******************************************************************************/
package org.eclipse.jdt.internal.junit.runner.junit3;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.jdt.internal.junit.runner.FailuresFirstPrioritizer;
import org.eclipse.jdt.internal.junit.runner.ITestLoader;
import org.eclipse.jdt.internal.junit.runner.ITestPrioritizer;
import org.eclipse.jdt.internal.junit.runner.ITestReference;
import org.eclipse.jdt.internal.junit.runner.JUnitMessages;
import org.eclipse.jdt.internal.junit.runner.NullPrioritizer;
import org.eclipse.jdt.internal.junit.runner.RemoteTestRunner;
public class JUnit3TestLoader implements ITestLoader {
private static final String SUITE_METHODNAME= "suite"; //$NON-NLS-1$
public static final String SET_UP_TEST_METHOD_NAME = "setUpTest"; //$NON-NLS-1$
// WANT: give test loaders a schema
public ITestReference[] loadTests(Class[] testClasses, String testName, String[] failureNames, String[] packages, String[][] includeExcludeTags, String uniqueId, RemoteTestRunner listener) {
// instantiate all tests
ITestReference[] suites= new ITestReference[testClasses.length];
ITestPrioritizer prioritizer;
if (failureNames != null)
prioritizer= new FailuresFirstPrioritizer(failureNames);
else
prioritizer= new NullPrioritizer();
for (int i= 0; i < suites.length; i++) {
Class testClassName= testClasses[i];
Test test= getTest(testClassName, testName, listener);
prioritizer.prioritize(test);
suites[i]= new JUnit3TestReference(test);
}
return suites;
}
private Test createTest(String testName, Class testClass) {
Class[] classArgs= { String.class };
Test test;
Constructor constructor= null;
try {
try {
constructor= testClass.getConstructor(classArgs);
test= (Test) constructor.newInstance(new Object[] { testName });
} catch (NoSuchMethodException e) {
// try the no arg constructor supported in 3.8.1
constructor= testClass.getConstructor(new Class[0]);
test= (Test) constructor.newInstance(new Object[0]);
if (test instanceof TestCase)
((TestCase) test).setName(testName);
}
if (test != null)
return test;
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
} catch (NoSuchMethodException e) {
} catch (ClassCastException e) {
}
return error(testName, "Could not create test \'" + testName + "\' "); //$NON-NLS-1$ //$NON-NLS-2$
}
public Test getTest(Class testClass, String testName, RemoteTestRunner failureListener) {
if (testName != null) {
return setupTest(testClass, createTest(testName, testClass), testName);
}
Method suiteMethod= null;
try {
suiteMethod= testClass.getMethod(JUnit3TestLoader.SUITE_METHODNAME, new Class[0]);
} catch (Exception e) {
// try to extract a test suite automatically
return new TestSuite(testClass);
}
if (!Modifier.isStatic(suiteMethod.getModifiers())) {
return error(JUnitMessages.getString("RemoteTestRunner.error"), JUnitMessages.getString("RemoteTestRunner.error.suite.notstatic"));//$NON-NLS-1$ //$NON-NLS-2$
}
try {
Test test= (Test) suiteMethod.invoke(null, new Class[0]); // static
if (test != null) {
return test;
}
return error(JUnitMessages.getString("RemoteTestRunner.error"), JUnitMessages.getString("RemoteTestRunner.error.suite.nullreturn")); //$NON-NLS-1$ //$NON-NLS-2$
} catch (InvocationTargetException e) {
String message= JUnitMessages.getFormattedString("RemoteTestRunner.error.invoke", e.getTargetException().toString()); //$NON-NLS-1$
failureListener.runFailed(message, e);
return new TestSuite(testClass);
} catch (IllegalAccessException e) {
String message= JUnitMessages.getFormattedString("RemoteTestRunner.error.invoke", e.toString()); //$NON-NLS-1$
failureListener.runFailed(message, e);
return new TestSuite(testClass);
}
}
/**
* Prepare a single test to be run standalone. If the test case class
* provides a static method Test setUpTest(Test test) then this method will
* be invoked. Instead of calling the test method directly the "decorated"
* test returned from setUpTest will be called. The purpose of this
* mechanism is to enable tests which requires a set-up to be run
* individually.
*
* @param reloadedTestClass test class
* @param reloadedTest test instance
* @param testName test name
* @return the reloaded test, or the test wrapped with setUpTest(..) if available
*/
private Test setupTest(Class reloadedTestClass, Test reloadedTest, String testName) {
if (reloadedTestClass == null)
return reloadedTest;
Method setup= null;
try {
setup= reloadedTestClass.getMethod(SET_UP_TEST_METHOD_NAME, new Class[] { Test.class });
} catch (SecurityException e1) {
return reloadedTest;
} catch (NoSuchMethodException e) {
return reloadedTest;
}
if (setup.getReturnType() != Test.class)
return error(testName, JUnitMessages.getString("RemoteTestRunner.error.notestreturn")); //$NON-NLS-1$
if (!Modifier.isPublic(setup.getModifiers()))
return error(testName, JUnitMessages.getString("RemoteTestRunner.error.shouldbepublic")); //$NON-NLS-1$
if (!Modifier.isStatic(setup.getModifiers()))
return error(testName, JUnitMessages.getString("RemoteTestRunner.error.shouldbestatic")); //$NON-NLS-1$
try {
Test test= (Test) setup.invoke(null, new Object[] { reloadedTest });
if (test == null)
return error(testName, JUnitMessages.getString("RemoteTestRunner.error.nullreturn")); //$NON-NLS-1$
return test;
} catch (IllegalArgumentException e) {
return error(testName, JUnitMessages.getFormattedString("RemoteTestRunner.error.couldnotinvoke", e)); //$NON-NLS-1$
} catch (IllegalAccessException e) {
return error(testName, JUnitMessages.getFormattedString("RemoteTestRunner.error.couldnotinvoke", e)); //$NON-NLS-1$
} catch (InvocationTargetException e) {
return error(testName, JUnitMessages.getFormattedString("RemoteTestRunner.error.invocationexception", e.getTargetException())); //$NON-NLS-1$
}
}
/**
* @param testName test name
* @param message error message
* @return a test which will fail and log an error message.
*/
private Test error(String testName, final String message) {
return new TestCase(testName) {
protected void runTest() {
fail(message);
}
};
}
}