This repository has been archived by the owner on Nov 9, 2017. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 57
/
QuarantiningRunner.java
109 lines (97 loc) · 4.6 KB
/
QuarantiningRunner.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// This implementation is copied from com.binarytweed.test.QuarantiningRunner
// in https://github.com/BinaryTweed/quarantining-test-runner v0.0.2
// with quarantine disabled for testFileClassName and
// delegateRunningToClassName.
// TODO see if we can remove this class when this issue is closed:
// https://github.com/BinaryTweed/quarantining-test-runner/issues/3
package org.zanata.test;
import java.lang.reflect.InvocationTargetException;
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.model.InitializationError;
import com.binarytweed.test.DelegateRunningToDiscoverer;
import com.binarytweed.test.QuarantinedPatternDiscoverer;
import com.binarytweed.test.QuarantiningUrlClassLoader;
/**
* Uses {@code QuarantiningUrlClassLoader} to load the test class, meaning the
* {@code Quarantine} annotation can be used to ensure certain classes are
* loaded separately.
*
* Use of a separate class loader allows classes to be reloaded for each test
* class, which is handy when you're testing frameworks that make use of static
* members.
*
* The selective quarantining is required because if the test class and its
* 'children' are all loaded by a different class loader, then the {@code Test}
* annotations yield different {@code Class} instances. JUnit then thinks there
* are no runnable methods, because it looks them up by Class.
*
* This implementation was modified (by Sean Flanigan) so that it no longer
* implicitly quarantines the Test class and the delegate Runner.
*/
public class QuarantiningRunner extends Runner {
private final Object innerRunner;
private final Class<?> innerRunnerClass;
private final DelegateRunningToDiscoverer delegateRunningToDiscoverer;
private final QuarantinedPatternDiscoverer quarantinedPatternDiscoverer;
public QuarantiningRunner(Class<?> testFileClass)
throws InitializationError {
delegateRunningToDiscoverer = new DelegateRunningToDiscoverer();
quarantinedPatternDiscoverer = new QuarantinedPatternDiscoverer();
Class<? extends Runner> delegateRunningTo =
delegateRunningToDiscoverer
.getDelegateRunningToOn(testFileClass);
String testFileClassName = testFileClass.getName();
String delegateRunningToClassName = delegateRunningTo.getName();
String[] quarantinedPatterns =
quarantinedPatternDiscoverer
.getQuarantinedPatternsOn(testFileClass);
// String[] allPatterns = Arrays.copyOf(quarantinedPatterns,
// quarantinedPatterns.length + 2);
// allPatterns[quarantinedPatterns.length] = testFileClassName;
// allPatterns[quarantinedPatterns.length + 1] =
// delegateRunningToClassName;
//
// QuarantiningUrlClassLoader classLoader = new
// QuarantiningUrlClassLoader(allPatterns);
QuarantiningUrlClassLoader classLoader =
new QuarantiningUrlClassLoader(quarantinedPatterns);
try {
innerRunnerClass =
classLoader.loadClass(delegateRunningToClassName);
Class<?> testClass = classLoader.loadClass(testFileClassName);
innerRunner =
innerRunnerClass.cast(innerRunnerClass.getConstructor(
Class.class).newInstance(testClass));
} catch (InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException
| ClassNotFoundException e) {
throw new InitializationError(e);
}
}
@Override
public Description getDescription() {
try {
return (Description) innerRunnerClass.getMethod("getDescription")
.invoke(innerRunner);
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException
| SecurityException e) {
throw new RuntimeException("Could not get description", e);
}
}
@Override
public void run(RunNotifier notifier) {
try {
innerRunnerClass.getMethod("run", RunNotifier.class).invoke(
innerRunner, notifier);
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException
| SecurityException e) {
notifier.fireTestFailure(new Failure(getDescription(), e));
}
}
}