189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmannpackage org.testng.junit;
289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
389f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmannimport java.util.*;
40e0cabeeb4d7b592ea9bc3ea7cd2318890b0418dLukas Jungmannimport java.util.regex.Pattern;
589f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmannimport org.junit.runner.Description;
689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmannimport org.junit.runner.JUnitCore;
789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmannimport org.junit.runner.Request;
889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmannimport org.junit.runner.Result;
91876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmannimport org.junit.runner.manipulation.Filter;
1089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmannimport org.junit.runner.notification.Failure;
1189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmannimport org.junit.runner.notification.RunListener;
121876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmannimport org.testng.*;
1389f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmannimport org.testng.collections.Lists;
1489f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmannimport org.testng.internal.ITestResultNotifier;
1589f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmannimport org.testng.internal.InvokedMethod;
1689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmannimport org.testng.internal.TestResult;
1789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
1889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann/**
1989f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann * A JUnit TestRunner that records/triggers all information/events necessary to
2089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann * TestNG.
2189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann *
2289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann * @author Lukas Jungmann
2389f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann */
2489f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmannpublic class JUnit4TestRunner implements IJUnitTestRunner {
2589f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
2689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    private ITestResultNotifier m_parentRunner;
2789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    private List<ITestNGMethod> m_methods = Lists.newArrayList();
2889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    private List<ITestListener> m_listeners = Lists.newArrayList();
290643910fcfd637e5b30f0719a6085ae8f1829785Julien Herr    private Collection<IInvokedMethodListener> m_invokeListeners = Lists.newArrayList();
3089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
3189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    public JUnit4TestRunner() {
3289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    }
3389f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
3489f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    public JUnit4TestRunner(ITestResultNotifier tr) {
3589f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        m_parentRunner = tr;
3689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        m_listeners = m_parentRunner.getTestListeners();
3789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    }
3889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
3989f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    /**
4089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann     * Needed from TestRunner in order to figure out what JUnit test methods
4189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann     * were run.
4289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann     *
4389f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann     * @return the list of all JUnit test methods run
4489f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann     */
4589f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    @Override
4689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    public List<ITestNGMethod> getTestMethods() {
4789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        return m_methods;
4889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    }
4989f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
5089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    @Override
5189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    public void setTestResultNotifier(ITestResultNotifier notifier) {
5289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        m_parentRunner = notifier;
5389f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        m_listeners = m_parentRunner.getTestListeners();
5489f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    }
5589f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
560643910fcfd637e5b30f0719a6085ae8f1829785Julien Herr    public void setInvokedMethodListeners(Collection<IInvokedMethodListener> listeners) {
571876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann        m_invokeListeners = listeners;
581876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann    }
591876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann
6089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    /**
6189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann     * A
6289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann     * <code>start</code> implementation that ignores the
6389f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann     * <code>TestResult</code>
6489f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann     *
6589f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann     * @param testClass the JUnit test class
6689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann     */
6789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    @Override
681876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann    public void run(Class testClass, String... methods) {
691876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann        start(testClass, methods);
7089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    }
7189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
7289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    /**
7389f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann     * Starts a test run. Analyzes the command line arguments and runs the given
7489f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann     * test suite.
7589f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann     */
761876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann    public Result start(final Class testCase, final String... methods) {
7789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        try {
7889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            JUnitCore core = new JUnitCore();
7989f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            core.addListener(new RL());
8089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            Request r = Request.aClass(testCase);
811876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann            return core.run(r.filterWith(new Filter() {
821876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann
831876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                @Override
841876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                public boolean shouldRun(Description description) {
851876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                    if (description == null) {
861876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                        return false;
871876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                    }
881876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                    if (methods.length == 0) {
891876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                        //run everything
901876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                        return true;
911876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                    }
921876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                    for (String m: methods) {
930e0cabeeb4d7b592ea9bc3ea7cd2318890b0418dLukas Jungmann                        Pattern p = Pattern.compile(m);
94b40b67f3b38e154c3ae4f1e318f5ef29d1b38d25Vladislav Rassokhin                        if (p.matcher(description.getMethodName()).matches()) {
95b40b67f3b38e154c3ae4f1e318f5ef29d1b38d25Vladislav Rassokhin                            return true;
96b40b67f3b38e154c3ae4f1e318f5ef29d1b38d25Vladislav Rassokhin                        }
971876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                    }
981876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                    return false;
991876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                }
1001876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann
1011876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                @Override
1021876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                public String describe() {
1031876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                    return "TestNG method filter";
1041876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                }
1051876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann            }));
10689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        } catch (Throwable t) {
10789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            throw new TestNGException("Failure in JUnit mode for class " + testCase.getName(), t);
10889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        }
10989f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    }
11089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
11189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    private class RL extends RunListener {
11289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
11310c223b7aa6bf34778079bb5ee1a494c83cd1239Ryan Schmitt        private Map<Description, ITestResult> runs = new WeakHashMap<>();
11410c223b7aa6bf34778079bb5ee1a494c83cd1239Ryan Schmitt        private List<Description> notified = new LinkedList<>();
11589f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
11689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        @Override
11789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        public void testAssumptionFailure(Failure failure) {
118273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin            notified.add(failure.getDescription());
11989f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            ITestResult tr = runs.get(failure.getDescription());
120273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin            tr.setStatus(TestResult.SKIP);
12189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            tr.setEndMillis(Calendar.getInstance().getTimeInMillis());
12289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            tr.setThrowable(failure.getException());
123273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin            m_parentRunner.addSkippedTest(tr.getMethod(), tr);
12489f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            for (ITestListener l : m_listeners) {
125273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin                l.onTestSkipped(tr);
12689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            }
12789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        }
12889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
12989f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        @Override
13089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        public void testFailure(Failure failure) throws Exception {
131273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin            if (isAssumptionFailed(failure)) {
132273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin                this.testAssumptionFailure(failure);
133273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin                return;
134273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin            }
135273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin            notified.add(failure.getDescription());
13689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            ITestResult tr = runs.get(failure.getDescription());
13789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            tr.setStatus(TestResult.FAILURE);
13889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            tr.setEndMillis(Calendar.getInstance().getTimeInMillis());
13989f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            tr.setThrowable(failure.getException());
1401876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann            m_parentRunner.addFailedTest(tr.getMethod(), tr);
14189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            for (ITestListener l : m_listeners) {
14289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann                l.onTestFailure(tr);
14389f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            }
14489f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        }
14589f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
14689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        @Override
14789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        public void testFinished(Description description) throws Exception {
14889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            ITestResult tr = runs.get(description);
149273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin            if (!notified.contains(description)) {
15089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann                tr.setStatus(TestResult.SUCCESS);
15189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann                tr.setEndMillis(Calendar.getInstance().getTimeInMillis());
1521876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                m_parentRunner.addPassedTest(tr.getMethod(), tr);
15389f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann                for (ITestListener l : m_listeners) {
15489f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann                    l.onTestSuccess(tr);
15589f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann                }
15689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            }
15789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            m_methods.add(tr.getMethod());
15889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        }
15989f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
16089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        @Override
16189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        public void testIgnored(Description description) throws Exception {
16289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            ITestResult tr = createTestResult(description);
16389f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            tr.setStatus(TestResult.SKIP);
16489f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            tr.setEndMillis(tr.getStartMillis());
1651876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann            m_parentRunner.addSkippedTest(tr.getMethod(), tr);
1661876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann            m_methods.add(tr.getMethod());
16789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            for (ITestListener l : m_listeners) {
16889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann                l.onTestSkipped(tr);
16989f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            }
17089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        }
17189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
17289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        @Override
17389f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        public void testRunFinished(Result result) throws Exception {
17489f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        }
17589f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
17689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        @Override
17789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        public void testRunStarted(Description description) throws Exception {
17889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        }
17989f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
18089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        @Override
18189f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        public void testStarted(Description description) throws Exception {
18289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            ITestResult tr = createTestResult(description);
18389f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            runs.put(description, tr);
18489f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            for (ITestListener l : m_listeners) {
18589f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann                l.onTestStart(tr);
18689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            }
18789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        }
18889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
18989f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        private ITestResult createTestResult(Description test) {
1901876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann            JUnit4TestClass tc = new JUnit4TestClass(test);
1911876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann            JUnitTestMethod tm = new JUnit4TestMethod(tc, test);
19289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
19389f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            TestResult tr = new TestResult(tc,
19489f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann                    test,
19589f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann                    tm,
19689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann                    null,
19789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann                    Calendar.getInstance().getTimeInMillis(),
1982e805d9db0e08d715b62bb47a8f7da07d831c0a1Lukas Jungmann                    0,
1992e805d9db0e08d715b62bb47a8f7da07d831c0a1Lukas Jungmann                    null);
20089f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann
20100234ed4e19c38374d0bbd5bc2de771c90b16209Julien Herr            InvokedMethod im = new InvokedMethod(tr.getTestClass(), tr.getMethod(), new Object[0], tr.getStartMillis(), tr);
2021876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann            m_parentRunner.addInvokedMethod(im);
2031876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann            for (IInvokedMethodListener l: m_invokeListeners) {
2041876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann                l.beforeInvocation(im, tr);
2051876355ae9a570f93b2222d9d03599712d732ca1Lukas Jungmann            }
20689f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann            return tr;
20789f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann        }
20889f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann    }
209273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin
210273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin    private static boolean isAssumptionFailed(Failure failure) {
211273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin        if (failure == null) {
212273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin            return false;
213273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin        }
214273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin        //noinspection ThrowableResultOfMethodCallIgnored
215273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin        final Throwable exception = failure.getException();
216273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin        //noinspection SimplifiableIfStatement
217273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin        if (exception == null) {
218273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin            return false;
219273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin        }
220273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin        return "org.junit.internal.AssumptionViolatedException".equals(exception.getClass().getCanonicalName());
221273426adec7bf37d0b8f55f1ab89db8363ca9f84Vladislav Rassokhin    }
22289f3b060dc074d4414e8e1dca409f74278278646Lukas Jungmann}
223