Concurrent JUnit testing Concurrent JUnit testing multithreading multithreading

Concurrent JUnit testing


Are you fixed to JUnit? TestNG provides good multi thread testing out of the box and it's compatible with JUnit tests (you need to make a few changes). For example you could run a test like this:

@Test(threadPoolSize = 3, invocationCount = 9,  timeOut = 10000)public void doSomething() {...}

This would mean that the doSomething() method will be invoked 9 times by 3 different threads.

I highly recommend TestNG.


I was looking for an answer to exactly this question, and based on the answers here, and what I read elsewhere, it appears as if there isn't currently an easy out-of-the-box way to run existing tests in parallel using JUnit. Or if there is I didn't find it. So I wrote a simple JUnit Runner that accomplishes that. Please feel free to use it; see http://falutin.net/2012/12/30/multithreaded-testing-with-junit/ for a complete explanation and the source code of the MultiThreadedRunner class. With this class, you can just annotate your existing test class(es) like this:

@RunWith(MultiThreadedRunner.class)


The following code should achieve your requirements which was taken from the German book JUnit Profiwissen which contains some hints to either tests stuff in parallel or on how to reduce execution time through using multiple cores instead of only a single core.

JUnit 4.6 introduced a ParallelComputer class which offered the parallel execution of tests. However, this functionality was not publicly accessible until JUnit 4.7 which provided the possibility to set a custom scheduler for the parent runner.

public class ParallelScheduler implements RunnerScheduler {    private ExecutorService threadPool = Executors.newFixedThreadPool(        Runtime.getRuntime().availableProcessors());    @Override    public void schedule(Runnable childStatement) {        threadPool.submit(childStatement);    }    @Override    public void finished() {        try {            threadPool.shutdown();            threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);        } catch (InterruptedException e) {            Thread.currentThread().interrupt();            throw new RuntimeException("Got interrupted", e);        }    }}public class ParallelRunner extends BlockJUnit4ClassRunner {    public ParallelRunner(Class<?> klass) throws InitializationError {        super(klass);        setScheduler(new ParallelScheduler());    }}

If you now annotate a test-class with @RunWith(ParallelRunner.class) each method will run within its own thread. Furthermore, there will be as many active threads (only) as CPU-cores are available at the executing machine.

If multiple classes should be executed in parallel you can define a customized suite like this:

public class ParallelSuite extends Suite {    public ParallelSuite(Class<?> klass, RunnerBuilder builder)       throws InitializationError {        super(klass, builder);        setScheduler(new ParallelScheduler());    }}

and then change @RunWith(Suite.class) with @RunWith(ParallelSuite.class)

You can even leverage the functionality of f.e. the WildcardPatternSuite by extending directly from that suite instead of Suite as in the example before. This enables you furthermore to filter unit-tests f.e. by any @Category - a TestSuite which only executes UnitTest annotated categories in parallel could look like this:

public interface UnitTest {}@RunWith(ParallelSuite.class)@SuiteClasses("**/*Test.class")@IncludeCategories(UnitTest.class)public class UnitTestSuite {}

A simple test case could now look like this:

@Category(UnitTest.class)@RunWith(MockitoJUnitRunner.class)public class SomeClassTest {    @Test    public void testSomething() {        ...    }}

The UnitTestSuite will execute each class found in subdirecotries that ends with Test and has a @Category(UnitTest.class) specified in parallel - depending on the number of CPU cores available.

I'm not sure if it can get simpler than that :)