JUnit4TestRunner.java revision 89f3b060dc074d4414e8e1dca409f74278278646
1package org.testng.junit;
2
3import java.util.*;
4import org.junit.runner.Description;
5import org.junit.runner.JUnitCore;
6import org.junit.runner.Request;
7import org.junit.runner.Result;
8import org.junit.runner.notification.Failure;
9import org.junit.runner.notification.RunListener;
10import org.testng.ITestListener;
11import org.testng.ITestNGMethod;
12import org.testng.ITestResult;
13import org.testng.TestNGException;
14import org.testng.collections.Lists;
15import org.testng.internal.ITestResultNotifier;
16import org.testng.internal.InvokedMethod;
17import org.testng.internal.TestResult;
18
19/**
20 * A JUnit TestRunner that records/triggers all information/events necessary to
21 * TestNG.
22 *
23 * @author Lukas Jungmann
24 */
25public class JUnit4TestRunner implements IJUnitTestRunner {
26
27    private ITestResultNotifier m_parentRunner;
28    private List<ITestNGMethod> m_methods = Lists.newArrayList();
29    private List<ITestListener> m_listeners = Lists.newArrayList();
30
31    public JUnit4TestRunner() {
32    }
33
34    public JUnit4TestRunner(ITestResultNotifier tr) {
35        m_parentRunner = tr;
36        m_listeners = m_parentRunner.getTestListeners();
37    }
38
39    /**
40     * Needed from TestRunner in order to figure out what JUnit test methods
41     * were run.
42     *
43     * @return the list of all JUnit test methods run
44     */
45    @Override
46    public List<ITestNGMethod> getTestMethods() {
47        return m_methods;
48    }
49
50    @Override
51    public void setTestResultNotifier(ITestResultNotifier notifier) {
52        m_parentRunner = notifier;
53        m_listeners = m_parentRunner.getTestListeners();
54    }
55
56    /**
57     * A
58     * <code>start</code> implementation that ignores the
59     * <code>TestResult</code>
60     *
61     * @param testClass the JUnit test class
62     */
63    @Override
64    public void run(Class testClass) {
65        start(testClass);
66    }
67
68    /**
69     * Starts a test run. Analyzes the command line arguments and runs the given
70     * test suite.
71     */
72    public Result start(Class testCase) {
73        try {
74            JUnitCore core = new JUnitCore();
75            core.addListener(new RL());
76            Request r = Request.aClass(testCase);
77            return core.run(r);
78        } catch (Throwable t) {
79            throw new TestNGException("Failure in JUnit mode for class " + testCase.getName(), t);
80        }
81    }
82
83    private class RL extends RunListener {
84
85        private Map<Description, ITestResult> runs = new WeakHashMap<Description, ITestResult>();
86        private List<Description> failures = new LinkedList<Description>();
87
88        @Override
89        public void testAssumptionFailure(Failure failure) {
90            super.testAssumptionFailure(failure);
91            ITestResult tr = runs.get(failure.getDescription());
92            tr.setStatus(TestResult.FAILURE);
93            tr.setEndMillis(Calendar.getInstance().getTimeInMillis());
94            tr.setThrowable(failure.getException());
95            for (ITestListener l : m_listeners) {
96                l.onTestFailure(tr);
97            }
98        }
99
100        @Override
101        public void testFailure(Failure failure) throws Exception {
102            super.testFailure(failure);
103            failures.add(failure.getDescription());
104            ITestResult tr = runs.get(failure.getDescription());
105            tr.setStatus(TestResult.FAILURE);
106            tr.setEndMillis(Calendar.getInstance().getTimeInMillis());
107            tr.setThrowable(failure.getException());
108            for (ITestListener l : m_listeners) {
109                l.onTestFailure(tr);
110            }
111        }
112
113        @Override
114        public void testFinished(Description description) throws Exception {
115            super.testFinished(description);
116            ITestResult tr = runs.get(description);
117            if (!failures.contains(description)) {
118                tr.setStatus(TestResult.SUCCESS);
119                tr.setEndMillis(Calendar.getInstance().getTimeInMillis());
120                for (ITestListener l : m_listeners) {
121                    l.onTestSuccess(tr);
122                }
123            }
124            m_parentRunner.addInvokedMethod(new InvokedMethod(tr.getTestClass(), tr.getMethod(), new Object[0], true, false, tr.getStartMillis()));
125            m_methods.add(tr.getMethod());
126        }
127
128        @Override
129        public void testIgnored(Description description) throws Exception {
130            super.testIgnored(description);
131            ITestResult tr = createTestResult(description);
132            tr.setStatus(TestResult.SKIP);
133            tr.setEndMillis(tr.getStartMillis());
134            for (ITestListener l : m_listeners) {
135                l.onTestSkipped(tr);
136            }
137            m_parentRunner.addInvokedMethod(new InvokedMethod(tr.getTestClass(), tr.getMethod(), new Object[0], true, false, tr.getStartMillis()));
138            m_methods.add(tr.getMethod());
139        }
140
141        @Override
142        public void testRunFinished(Result result) throws Exception {
143            super.testRunFinished(result);
144            //TODO: ITestContext to be implemented by JUnitTestRunner
145        }
146
147        @Override
148        public void testRunStarted(Description description) throws Exception {
149            super.testRunStarted(description);
150            //TODO: ITestContext to be implemented by JUnitTestRunner
151        }
152
153        @Override
154        public void testStarted(Description description) throws Exception {
155            super.testStarted(description);
156            ITestResult tr = createTestResult(description);
157            runs.put(description, tr);
158            for (ITestListener l : m_listeners) {
159                l.onTestStart(tr);
160            }
161        }
162
163        private ITestResult createTestResult(Description test) {
164            JUnitUtils.JUnitTestClass tc = new JUnitUtils.JUnitTestClass(test);
165            JUnitUtils.JUnitTestMethod tm = new JUnitUtils.JUnitTestMethod(test, tc);
166
167            TestResult tr = new TestResult(tc,
168                    test,
169                    tm,
170                    null,
171                    Calendar.getInstance().getTimeInMillis(),
172                    0);
173
174            return tr;
175        }
176    }
177}
178