CVS: junit/src/org/junit/internal/runners TestMethod.java, NONE, 1.1 TestClassMethodsRunner.java, 1.1, 1.2 TestIntrospector.java, 1.2, 1.3
David Saff <[email protected]>
| Newsgroups | gmane.comp.java.junit.devel |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/junit/junit/src/org/junit/internal/runners
In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv23274/src/org/junit/internal/runners
Modified Files:
TestClassMethodsRunner.java TestIntrospector.java
Added Files:
TestMethod.java
Log Message:
Another potential enhancement. RunMethodWith allows individual test methods to be run with different runners.
--- NEW FILE: TestMethod.java ---
package org.junit.internal.runners;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import org.junit.runner.Description;
import org.junit.runners.MethodRunner;
import org.junit.runners.RunMethodWith;
public class TestMethod {
private final Object fTest;
private final Method fJavaMethod;
private final Description fDescription;
public TestMethod(Object test, Method javaMethod, Description description) {
fTest= test;
fJavaMethod= javaMethod;
fDescription= description;
}
public Description getDescription() {
return fDescription;
}
public Object getTest() {
return fTest;
}
public Method getJavaMethod() {
return fJavaMethod;
}
MethodRunner findCustomRunner(TestClassMethodsRunner testClassMethodsRunner)
throws Exception {
Method method= getJavaMethod();
AnnotatedElement method2= method;
MethodRunner methodRunner= createCustomRunner(method2);
if (methodRunner != null)
return methodRunner;
for (Annotation a : method2.getAnnotations()) {
AnnotatedElement annotationType= a.annotationType();
MethodRunner arunner= createCustomRunner(annotationType);
if (arunner != null)
return arunner;
}
return null;
}
private MethodRunner createCustomRunner(AnnotatedElement annotationType)
throws Exception {
RunMethodWith runMethodWith= annotationType
.getAnnotation(RunMethodWith.class);
if (runMethodWith != null)
return runMethodWith.value().newInstance();
return null;
}
}
Index: TestClassMethodsRunner.java
===================================================================
RCS file: /cvsroot/junit/junit/src/org/junit/internal/runners/TestClassMethodsRunner.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- TestClassMethodsRunner.java 21 Nov 2006 18:53:34 -0000 1.1
+++ TestClassMethodsRunner.java 27 Dec 2006 22:27:22 -0000 1.2
@@ -17,28 +17,33 @@
import org.junit.runner.manipulation.Sorter;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.MethodRunner;
-public class TestClassMethodsRunner extends Runner implements Filterable, Sortable {
+public class TestClassMethodsRunner extends Runner implements Filterable,
+ Sortable {
private final List<Method> fTestMethods;
+
private final Class<?> fTestClass;
- // This assumes that some containing runner will perform validation of the test methods
+ // This assumes that some containing runner will perform validation of the
+ // test methods
public TestClassMethodsRunner(Class<?> klass) {
fTestClass= klass;
- fTestMethods= new TestIntrospector(getTestClass()).getTestMethods(Test.class);
+ fTestMethods= new TestIntrospector(getTestClass())
+ .getTestMethods(Test.class);
}
-
+
@Override
public void run(RunNotifier notifier) {
if (fTestMethods.isEmpty())
- testAborted(notifier, getDescription(), new Exception("No runnable methods"));
+ testAborted(notifier, getDescription(), new Exception(
+ "No runnable methods"));
for (Method method : fTestMethods)
invokeTestMethod(method, notifier);
}
- private void testAborted(RunNotifier notifier, Description description, Throwable cause) {
- // TODO: duped!
- // TODO: envious
+ private void testAborted(RunNotifier notifier, Description description,
+ Throwable cause) {
notifier.fireTestStarted(description);
notifier.fireTestFailure(new Failure(description, cause));
notifier.fireTestFinished(description);
@@ -49,14 +54,14 @@
Description spec= Description.createSuiteDescription(getName());
List<Method> testMethods= fTestMethods;
for (Method method : testMethods)
- spec.addChild(methodDescription(method));
+ spec.addChild(methodDescription(method));
return spec;
}
protected String getName() {
return getTestClass().getName();
}
-
+
protected Object createTest() throws Exception {
return getTestClass().getConstructor().newInstance();
}
@@ -66,17 +71,38 @@
try {
test= createTest();
} catch (InvocationTargetException e) {
- testAborted(notifier, methodDescription(method), e.getCause());
- return;
- } catch (Exception e) {
- testAborted(notifier, methodDescription(method), e);
+ testAborted(notifier, method, e.getCause());
+ return;
+ } catch (Throwable e) {
+ testAborted(notifier, method, e);
return;
}
- createMethodRunner(test, method, notifier).run();
+
+ TestMethod testMethod= new TestMethod(test, method,
+ methodDescription(method));
+ try {
+ MethodRunner runner= testMethod.findCustomRunner(this);
+ if (runner == null)
+ createMethodRunner(test, method, notifier).run();
+ else {
+ runner.run(testMethod, notifier);
+ }
+ } catch (Exception e) {
+ Throwable exception= new RuntimeException(
+ "Exception creating custom method runner", e);
+ testAborted(notifier, method, exception);
+ }
}
- protected TestMethodRunner createMethodRunner(Object test, Method method, RunNotifier notifier) {
- return new TestMethodRunner(test, method, notifier, methodDescription(method));
+ private void testAborted(RunNotifier notifier, Method method,
+ Throwable cause) {
+ testAborted(notifier, methodDescription(method), cause);
+ }
+
+ protected TestMethodRunner createMethodRunner(Object test, Method method,
+ RunNotifier notifier) {
+ return new TestMethodRunner(test, method, notifier,
+ methodDescription(method));
}
protected String testName(Method method) {
@@ -84,7 +110,8 @@
}
protected Description methodDescription(Method method) {
- return Description.createTestDescription(getTestClass(), testName(method));
+ return Description.createTestDescription(getTestClass(),
+ testName(method));
}
public void filter(Filter filter) throws NoTestsRemainException {
@@ -100,7 +127,8 @@
public void sort(final Sorter sorter) {
Collections.sort(fTestMethods, new Comparator<Method>() {
public int compare(Method o1, Method o2) {
- return sorter.compare(methodDescription(o1), methodDescription(o2));
+ return sorter.compare(methodDescription(o1),
+ methodDescription(o2));
}
});
}
Index: TestIntrospector.java
===================================================================
RCS file: /cvsroot/junit/junit/src/org/junit/internal/runners/TestIntrospector.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- TestIntrospector.java 27 Dec 2006 17:45:54 -0000 1.2
+++ TestIntrospector.java 27 Dec 2006 22:27:22 -0000 1.3
@@ -11,6 +11,7 @@
import org.junit.Ignore;
import org.junit.Test;
import org.junit.Test.None;
+import org.junit.runners.Replaces;
public class TestIntrospector {
private static class MethodCollector {
@@ -24,21 +25,36 @@
public MethodCollector addMethods(Class<?> testClass) {
for (Method eachMethod : testClass.getDeclaredMethods()) {
- Annotation annotation= eachMethod
- .getAnnotation(annotationClass);
- if (annotation != null && !isShadowed(eachMethod))
+ if (hasAnnotation(eachMethod) && !isShadowed(eachMethod))
methods.add(eachMethod);
}
-
- addSuperclasses(testClass);
+
+ addSuperclasses(testClass);
addMixins(testClass);
return this;
}
+ private boolean hasAnnotation(Method method) {
+ return method.getAnnotation(annotationClass) != null
+ || hasReplacementAnnotation(method);
+ }
+
+ private boolean hasReplacementAnnotation(Method method) {
+ Annotation[] annotations= method.getAnnotations();
+ for (Annotation annotation : annotations) {
+ Replaces replaces= annotation.annotationType().getAnnotation(
+ Replaces.class);
+ if (replaces != null
+ && replaces.value().equals(annotationClass))
+ return true;
+ }
+ return false;
+ }
+
private void addMixins(Class<?> testClass) {
MixIn mixins= testClass.getAnnotation(MixIn.class);
if (mixins != null)
- for (Class<?> type : mixins.value())
+ for (Class<?> type : mixins.value())
addMethods(type);
}
@@ -90,8 +106,8 @@
return results;
}
- public boolean isIgnored(Method eachMethod) {
- return eachMethod.getAnnotation(Ignore.class) != null;
+ public boolean isIgnored(Method method) {
+ return method.getAnnotation(Ignore.class) != null;
}
private boolean runsTopToBottom(Class<? extends Annotation> annotation) {
@@ -101,12 +117,15 @@
long getTimeout(Method method) {
Test annotation= method.getAnnotation(Test.class);
- long timeout= annotation.timeout();
- return timeout;
+ if (annotation == null)
+ return 0;
+ return annotation.timeout();
}
Class<? extends Throwable> expectedException(Method method) {
Test annotation= method.getAnnotation(Test.class);
+ if (annotation == null)
+ return null;
if (annotation.expected() == None.class)
return null;
else
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV