4

To execute my JUnit tests in parallel I have used the solution provided here (Thanks to @peanut & @Reid Mac ). This works well for JUnit 4 but I'm trying to migrate from JUnit 4 to JUnit 5. Since JUnit 5 tests are executed by JUnitPlatform, which extends directly Runner, the equivalent is not possible with JUnit 5. Does JUnit 5 have any method like setScheduler? Below are my code snippets.

JUnit4Runner.class

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerBuilder;
import org.junit.runners.model.RunnerScheduler;

public final class JUnit4Runner extends Suite {


    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.TYPE })
    public @interface Concurrent {
        int threads() default 1;
    }

    /**
     * Used by JUnit Concurrent
     * https://stackoverflow.com/questions/5674774/running-junit-test-in-parallel-on-suite-level
     */
    public AJUnit4Runner2(Class<?> suiteClass, RunnerBuilder builder) throws InitializationError {
        super(suiteClass, builder);
        setScheduler(new RunnerScheduler() {
            ExecutorService executorService = Executors.newFixedThreadPool(
                    suiteClass.isAnnotationPresent(Concurrent.class)
                            ? suiteClass.getAnnotation(Concurrent.class).threads()
                            : 1,
                    new NamedThreadFactory(suiteClass.getSimpleName()));
            CompletionService<Void> completionService = new ExecutorCompletionService<Void>(executorService);
            Queue<Future<Void>> tasks = new LinkedList<Future<Void>>();

            @Override
            public void schedule(Runnable childStatement) {
                tasks.offer(completionService.submit(childStatement, null));
            }

            @Override
            public void finished() {
                try {
                    while (!tasks.isEmpty()) {
                        tasks.remove(completionService.take());
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    while (!tasks.isEmpty()) {
                        tasks.poll().cancel(true);
                    }
                    executorService.shutdownNow();
                }
            }
        });
    }

    class NamedThreadFactory implements ThreadFactory {

        final AtomicInteger poolNumber = new AtomicInteger(1);
        final AtomicInteger threadNumber = new AtomicInteger(1);
        final ThreadGroup group;

        public NamedThreadFactory(String poolName) {
            group = new ThreadGroup(poolName + "-" + poolNumber.getAndIncrement());
        }

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(group, r, group.getName() + "-thread-" + threadNumber.getAndIncrement(), 0);
        }
    }

}

JUnit5 runner class looks something like this

JUnit5Runner.class

public class JUnit5Runner extends JUnitPlatform {
    public JUnit5Runner(Class<?> testClass) throws InitializationError {
        super(testClass);
        ...
    }

    @Override
    public void run(RunNotifier notifier) {
        super.run(notifier);
    }
}
victor gallet
  • 1,819
  • 17
  • 25
Balu
  • 141
  • 3
  • 17

1 Answers1

2

Junit 5.3 M1 now does support parallel test execution. As it mentioned in the documentation, it is currently an experimental feature. You can enable it by setting the junit.jupiter.execution.parallel.enabled configuration parameter to true in junit-platform.properties.

victor gallet
  • 1,819
  • 17
  • 25