📄 bulktest.java
字号:
* The class is examined for simple and bulk test methods; any child
* bulk tests are also examined recursively; and the results are stored
* in a hierarchal {@link TestSuite}.<P>
*
* The given class must be a subclass of <Code>BulkTest</Code> and must
* not be abstract.<P>
*
* @param c the class to examine for simple and bulk tests
* @return a {@link TestSuite} containing all the simple and bulk tests
* defined by that class
*/
public static TestSuite makeSuite(Class c) {
if (Modifier.isAbstract(c.getModifiers())) {
throw new IllegalArgumentException("Class must not be abstract.");
}
if (!BulkTest.class.isAssignableFrom(c)) {
throw new IllegalArgumentException("Class must extend BulkTest.");
}
return new BulkTestSuiteMaker(c).make();
}
}
// It was easier to use a separate class to do all the reflection stuff
// for making the TestSuite instances. Having permanent state around makes
// it easier to handle the recursion.
class BulkTestSuiteMaker {
/** The class that defines simple and bulk tests methods. */
private Class startingClass;
/** List of ignored simple test names. */
private List ignored;
/** The TestSuite we're currently populating. Can change over time. */
private TestSuite result;
/**
* The prefix for simple test methods. Used to check if a test is in
* the ignored list.
*/
private String prefix;
/**
* Constructor.
*
* @param startingClass the starting class
*/
public BulkTestSuiteMaker(Class startingClass) {
this.startingClass = startingClass;
}
/**
* Makes a hierarchal TestSuite based on the starting class.
*
* @return the hierarchal TestSuite for startingClass
*/
public TestSuite make() {
this.result = new TestSuite();
this.prefix = getBaseName(startingClass);
result.setName(prefix);
BulkTest bulk = makeFirstTestCase(startingClass);
ignored = new ArrayList();
String[] s = bulk.ignoredSimpleTests();
if (s != null) {
ignored.addAll(Arrays.asList(s));
}
make(bulk);
return result;
}
/**
* Appends all the simple tests and bulk tests defined by the given
* instance's class to the current TestSuite.
*
* @param bulk An instance of the class that defines simple and bulk
* tests for us to append
*/
void make(BulkTest bulk) {
Class c = bulk.getClass();
Method[] all = c.getMethods();
for (int i = 0; i < all.length; i++) {
if (isTest(all[i])) addTest(bulk, all[i]);
if (isBulk(all[i])) addBulk(bulk, all[i]);
}
}
/**
* Adds the simple test defined by the given method to the TestSuite.
*
* @param bulk The instance of the class that defined the method
* (I know it's wierd. But the point is, we can clone the instance
* and not have to worry about constructors.)
* @param m The simple test method
*/
void addTest(BulkTest bulk, Method m) {
BulkTest bulk2 = (BulkTest)bulk.clone();
bulk2.setName(m.getName());
bulk2.verboseName = prefix + "." + m.getName();
if (ignored.contains(bulk2.verboseName)) return;
result.addTest(bulk2);
}
/**
* Adds a whole new suite of tests that are defined by the result of
* the given bulk test method. In other words, the given bulk test
* method is invoked, and the resulting BulkTest instance is examined
* for yet more simple and bulk tests.
*
* @param bulk The instance of the class that defined the method
* @param m The bulk test method
*/
void addBulk(BulkTest bulk, Method m) {
BulkTest bulk2;
try {
bulk2 = (BulkTest)m.invoke(bulk, null);
if (bulk2 == null) return;
} catch (InvocationTargetException e) {
throw new Error(); // FIXME;
} catch (IllegalAccessException e) {
throw new Error(); // FIXME;
}
// Save current state on the stack.
String oldPrefix = prefix;
TestSuite oldResult = result;
prefix = prefix + "." + m.getName();
result = new TestSuite();
result.setName(m.getName());
make(bulk2);
oldResult.addTest(result);
// Restore the old state
prefix = oldPrefix;
result = oldResult;
}
/**
* Returns the base name of the given class.
*
* @param c the class
* @return the name of that class, minus any package names
*/
private static String getBaseName(Class c) {
String name = c.getName();
int p = name.lastIndexOf('.');
if (p > 0) {
name = name.substring(p + 1);
}
return name;
}
// These three methods are used to create a valid BulkTest instance
// from a class.
private static Constructor getTestCaseConstructor(Class c) {
try {
return c.getConstructor(new Class[] { String.class });
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException(c + " must provide " +
"a (String) constructor");
}
}
private static BulkTest makeTestCase(Class c, Method m) {
Constructor con = getTestCaseConstructor(c);
try {
return (BulkTest)con.newInstance(new String[] { m.getName() });
} catch (InvocationTargetException e) {
e.printStackTrace();
throw new RuntimeException(); // FIXME;
} catch (IllegalAccessException e) {
throw new Error(); // should never occur
} catch (InstantiationException e) {
throw new RuntimeException(); // FIXME;
}
}
private static BulkTest makeFirstTestCase(Class c) {
Method[] all = c.getMethods();
for (int i = 0; i < all.length; i++) {
if (isTest(all[i])) return makeTestCase(c, all[i]);
}
throw new IllegalArgumentException(c.getName() + " must provide "
+ " at least one test method.");
}
/**
* Returns true if the given method is a simple test method.
*/
private static boolean isTest(Method m) {
if (!m.getName().startsWith("test")) return false;
if (m.getReturnType() != Void.TYPE) return false;
if (m.getParameterTypes().length != 0) return false;
int mods = m.getModifiers();
if (Modifier.isStatic(mods)) return false;
if (Modifier.isAbstract(mods)) return false;
return true;
}
/**
* Returns true if the given method is a bulk test method.
*/
private static boolean isBulk(Method m) {
if (!m.getName().startsWith("bulkTest")) return false;
if (m.getReturnType() != BulkTest.class) return false;
if (m.getParameterTypes().length != 0) return false;
int mods = m.getModifiers();
if (Modifier.isStatic(mods)) return false;
if (Modifier.isAbstract(mods)) return false;
return true;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -