junit-team / junit4

A programmer-oriented testing framework for Java.
https://junit.org/junit4
Eclipse Public License 1.0
8.52k stars 3.26k forks source link

JUnitCore could not invoke test #1763

Closed DmitriyKapeliukh closed 1 year ago

DmitriyKapeliukh commented 1 year ago

Hi folks!

I have a test automation framework based on Junit v4.13 with a custom test rerun option. Based on my business specific I'm triggering a rerun test from @AfterClass annotation when the first run fas failed. The annotated method has a lot of specific calls and the major is rerun @Test, code is below:

    private static void rerunTests() {
        logger.info("Init JUnitCore in " + new Throwable().getStackTrace()[0].getMethodName());
        JUnitCore junit = new JUnitCore();
        Result run = junit.run(TestRunner.class);
        logger.info("Invoke JUnit run " + new Throwable().getStackTrace()[0].getMethodName());
        if (!run.wasSuccessful()) {
            List<Failure> failures = run.getFailures();
            logger.info("Failed tests: ");
            failures.forEach((failure -> logger.info(failure.getTestHeader())));
            System.exit(1);
        }
    }

The problem is the rerun phase is stuck from time to time and the is no reason for that. So Juint could not run the failed test and the whole regression is stuck up to Jenkins pipeline timeout (4h). I've got a thread dump where the main thread waits for new JUnitCore() constructor. surefire.txt

Attached thread dump

kcooney commented 1 year ago

Looking at your stack trace, the main thread is not waiting for the JUnitCore constructor. It's blocked in some code in com.googlecode.junittoolbox.ParallelScheduler. I suggest reaching out to the maintainers of https://github.com/MichaelTamm/junit-toolbox for help.

I would be remiss to point out that what you are doing is highly nonstandard, and possibly problematic. By the time an @AfterClass static method is called, any failures have already been reported to the test listeners (unless you have a custom test runner that does the retries). In fact, the entire rerun is invisible to the installed test listeners and to any scheduler being used, which may be why things are failing.

I've seen some people do retries in a custom Rule (which can also be problematic, as any state on the test class that is created at construction time and not reset in a @Before or @After method may not have the correct value).