in src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java [588:681]
private static boolean containsTests(final Class<?> testClass, final boolean isJUnit4) {
Class<? extends Annotation> testAnnotation = null;
Class<? extends Annotation> suiteAnnotation = null;
Class<? extends Annotation> runWithAnnotation = null;
try {
testAnnotation =
Class.forName("org.junit.Test").asSubclass(Annotation.class);
} catch (final ClassNotFoundException e) {
if (isJUnit4) {
// odd - we think we're JUnit4 but don't support the test annotation. We therefore can't have any tests!
return false;
}
// else... we're a JUnit3 test and don't need the annotation
}
try {
suiteAnnotation = Class.forName("org.junit.Suite.SuiteClasses")
.asSubclass(Annotation.class);
} catch (final ClassNotFoundException ex) {
// ignore - we don't have this annotation so make sure we don't check for it
}
try {
runWithAnnotation = Class.forName("org.junit.runner.RunWith")
.asSubclass(Annotation.class);
} catch (final ClassNotFoundException ex) {
// also ignore as this annotation doesn't exist so tests can't use it
}
if (!isJUnit4 && !TestCase.class.isAssignableFrom(testClass)) {
//a test we think is JUnit3 but does not extend TestCase. Can't really be a test.
return false;
}
// check if we have any inner classes that contain suitable test methods
for (final Class<?> innerClass : testClass.getDeclaredClasses()) {
if (containsTests(innerClass, isJUnit4) || containsTests(innerClass, !isJUnit4)) {
return true;
}
}
if (Modifier.isAbstract(testClass.getModifiers())
|| Modifier.isInterface(testClass.getModifiers())) {
// can't instantiate class and no inner classes are tests either
return false;
}
if (isJUnit4) {
if (suiteAnnotation != null && testClass.getAnnotation(suiteAnnotation) != null) {
// class is marked as a suite. Let JUnit try and work its magic on it.
return true;
}
if (runWithAnnotation != null && testClass.getAnnotation(runWithAnnotation) != null) {
/* Class is marked with @RunWith. If this class is badly written (no test methods,
* multiple constructors, private constructor etc) then the class is automatically
* run and fails in the IDEs I've tried... so I'm happy handing the class to JUnit
* to try and run, and let JUnit report a failure if a bad test case is provided.
* Trying to do anything else is likely to result in us filtering out cases that
* could be valid for future versions of JUnit so would just increase future
* maintenance work.
*/
return true;
}
}
for (final Method m : testClass.getMethods()) {
if (isJUnit4) {
// check if suspected JUnit4 classes have methods with @Test annotation
if (m.getAnnotation(testAnnotation) != null) {
return true;
}
} else {
// check if JUnit3 class have public or protected no-args methods starting with
// names starting with test
if (m.getName().startsWith("test")
&& m.getParameterTypes().length == 0
&& (Modifier.isProtected(m.getModifiers())
|| Modifier.isPublic(m.getModifiers()))) {
return true;
}
}
// check if JUnit3 or JUnit4 test have a public or protected, static,
// no-args 'suite' method
if ("suite".equals(m.getName()) && m.getParameterTypes().length == 0
&& (Modifier.isProtected(m.getModifiers())
|| Modifier.isPublic(m.getModifiers()))
&& Modifier.isStatic(m.getModifiers())) {
return true;
}
}
// no test methods found
return false;
}