junit.framework.TestSuite Maven / Gradle / Ivy
package junit.framework;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
import org.junit.internal.MethodSorter;
/**
* A TestSuite
is a Composite
of Tests.
* It runs a collection of test cases. Here is an example using
* the dynamic test definition.
*
* TestSuite suite= new TestSuite();
* suite.addTest(new MathTest("testAdd"));
* suite.addTest(new MathTest("testDivideByZero"));
*
*
*
* Alternatively, a TestSuite can extract the tests to be run automatically.
* To do so you pass the class of your TestCase class to the
* TestSuite constructor.
*
* TestSuite suite= new TestSuite(MathTest.class);
*
*
*
* This constructor creates a suite with all the methods
* starting with "test" that take no arguments.
*
* A final option is to do the same for a large array of test classes.
*
* Class[] testClasses = { MathTest.class, AnotherTest.class }
* TestSuite suite= new TestSuite(testClasses);
*
*
*
* @see Test
*/
public class TestSuite implements Test
{
/**
* ...as the moon sets over the early morning Merlin, Oregon
* mountains, our intrepid adventurers type...
*/
static public Test createTest(Class> theClass, String name)
{
Constructor> constructor;
try
{
constructor= getTestConstructor(theClass);
}
catch (NoSuchMethodException e)
{
return warning("Class " + theClass.getName() + " has no public constructor TestCase(String name) or TestCase()");
}
Object test;
try
{
if (constructor.getParameterTypes().length == 0)
{
test= constructor.newInstance(new Object[0]);
if (test instanceof TestCase)
{
((TestCase) test).setName(name);
}
}
else
{
test= constructor.newInstance(new Object[] { name });
}
}
catch (InstantiationException e)
{
return (warning("Cannot instantiate test case: " + name + " (" + exceptionToString(e) + ")"));
}
catch (InvocationTargetException e)
{
return (warning("Exception in constructor: " + name + " (" + exceptionToString(e.getTargetException()) + ")"));
}
catch (IllegalAccessException e)
{
return (warning("Cannot access test case: " + name + " (" + exceptionToString(e) + ")"));
}
return (Test) test;
}
/**
* Gets a constructor which takes a single String as
* its argument or a no arg constructor.
*/
public static Constructor> getTestConstructor(Class> theClass) throws NoSuchMethodException
{
try
{
return theClass.getConstructor(String.class);
}
catch (NoSuchMethodException e)
{
// fall through
}
return theClass.getConstructor(new Class[0]);
}
/**
* Returns a test which will fail and log a warning message.
*/
public static Test warning(final String message)
{
return new TestCase("warning")
{
@Override
protected void runTest()
{
fail(message);
}
};
}
/**
* Converts the stack trace into a string
*/
private static String exceptionToString(Throwable t)
{
StringWriter stringWriter= new StringWriter();
PrintWriter writer= new PrintWriter(stringWriter);
t.printStackTrace(writer);
return stringWriter.toString();
}
private String fName;
private Vector fTests= new Vector(10); // Cannot convert this to List because it is used directly by some test runners
/**
* Constructs an empty TestSuite.
*/
public TestSuite()
{
}
/**
* Constructs a TestSuite from the given class. Adds all the methods
* starting with "test" as test cases to the suite.
* Parts of this method were written at 2337 meters in the Hueffihuette,
* Kanton Uri
*/
public TestSuite(final Class> theClass)
{
addTestsFromTestCase(theClass);
}
private void addTestsFromTestCase(final Class> theClass)
{
fName= theClass.getName();
try
{
getTestConstructor(theClass); // Avoid generating multiple error messages
}
catch (NoSuchMethodException e)
{
addTest(warning("Class " + theClass.getName() + " has no public constructor TestCase(String name) or TestCase()"));
return;
}
if (!Modifier.isPublic(theClass.getModifiers()))
{
addTest(warning("Class " + theClass.getName() + " is not public"));
return;
}
Class> superClass= theClass;
List names= new ArrayList();
while (Test.class.isAssignableFrom(superClass))
{
for (Method each : MethodSorter.getDeclaredMethods(superClass))
{
addTestMethod(each, names, theClass);
}
superClass= superClass.getSuperclass();
}
if (fTests.size() == 0)
{
addTest(warning("No tests found in " + theClass.getName()));
}
}
/**
* Constructs a TestSuite from the given class with the given name.
*
* @see TestSuite#TestSuite(Class)
*/
public TestSuite(Class extends TestCase> theClass, String name)
{
this(theClass);
setName(name);
}
/**
* Constructs an empty TestSuite.
*/
public TestSuite(String name)
{
setName(name);
}
/**
* Constructs a TestSuite from the given array of classes.
*
* @param classes {@link TestCase}s
*/
public TestSuite(Class>... classes)
{
for (Class> each : classes)
{
addTest(testCaseForClass(each));
}
}
private Test testCaseForClass(Class> each)
{
if (TestCase.class.isAssignableFrom(each))
{
return new TestSuite(each.asSubclass(TestCase.class));
}
else
{
return warning(each.getCanonicalName() + " does not extend TestCase");
}
}
/**
* Constructs a TestSuite from the given array of classes with the given name.
*
* @see TestSuite#TestSuite(Class[])
*/
public TestSuite(Class extends TestCase>[] classes, String name)
{
this(classes);
setName(name);
}
/**
* Adds a test to the suite.
*/
public void addTest(Test test)
{
fTests.add(test);
}
/**
* Adds the tests from the given class to the suite
*/
public void addTestSuite(Class extends TestCase> testClass)
{
addTest(new TestSuite(testClass));
}
/**
* Counts the number of test cases that will be run by this test.
*/
public int countTestCases()
{
int count= 0;
for (Test each : fTests)
{
count+= each.countTestCases();
}
return count;
}
/**
* Returns the name of the suite. Not all
* test suites have a name and this method
* can return null.
*/
public String getName()
{
return fName;
}
/**
* Runs the tests and collects their result in a TestResult.
*/
public void run(TestResult result)
{
for (Test each : fTests)
{
if (result.shouldStop())
{
break;
}
runTest(each, result);
}
}
public void runTest(Test test, TestResult result)
{
test.run(result);
}
/**
* Sets the name of the suite.
*
* @param name the name to set
*/
public void setName(String name)
{
fName= name;
}
/**
* Returns the test at the given index
*/
public Test testAt(int index)
{
return fTests.get(index);
}
/**
* Returns the number of tests in this suite
*/
public int testCount()
{
return fTests.size();
}
/**
* Returns the tests as an enumeration
*/
public Enumeration tests()
{
return fTests.elements();
}
/**
*/
@Override
public String toString()
{
if (getName() != null)
{
return getName();
}
return super.toString();
}
private void addTestMethod(Method m, List names, Class> theClass)
{
String name= m.getName();
if (names.contains(name))
{
return;
}
if (!isPublicTestMethod(m))
{
if (isTestMethod(m))
{
addTest(warning("Test method isn't public: " + m.getName() + "(" + theClass.getCanonicalName() + ")"));
}
return;
}
names.add(name);
addTest(createTest(theClass, name));
}
private boolean isPublicTestMethod(Method m)
{
return isTestMethod(m) && Modifier.isPublic(m.getModifiers());
}
private boolean isTestMethod(Method m)
{
return m.getParameterTypes().length == 0 && m.getName().startsWith("test") && m.getReturnType().equals(Void.TYPE);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy