Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running Tests in Parallel with Junit [duplicate]

I would like to run every method annotated with @Test, across multiple classes, at the same time. For some cases, I would like to limit this, and say that only 100 total can run at any one time. I would like methods with @BeforeClass annotations to be run once before any Test in a class runs, and I would like @AfterClass annotations to be run once after all Tests in a class run. I would like System.out, System.err, and Exceptions to be appropriately buffered/captured rather than written out, so that they don't interleave, and I can read the final output and understand what happened.

Does this exist? I have a large number of independent test cases, and my application is (I believe) threadsafe. None of these tests have dependencies out of the JVM, and I want to finish them as quickly as possible, given my hardware.

If this doesn't exist, is there a concrete reason why not? How much time is lost by junit users worldwide because this isn't easy? Can I build it into Junit? In my mind, this should be as simple as a single flag, and it "just works".

like image 364
Cory Kendall Avatar asked Nov 14 '15 00:11

Cory Kendall


2 Answers

You can accomplish this with JUnit's ParallelComputer (note it's still considered experimental). It's a pretty simple implementation which is backed by the java.util.concurrent.ExecutorService API.
If you're curious how it works, check out the source.

Basically you call JUnitCore.runClasses(Computer, Classes ...) and pass in a ParallelComputer object for the first argument.

Example usage:

import org.junit.Test;
import org.junit.experimental.ParallelComputer;
import org.junit.runner.JUnitCore;

public class ParallelComputerExample {

    @Test
    public void runAllTests() {
        Class<?>[] classes = { ParallelTest1.class, ParallelTest2.class };

        // ParallelComputer(true,true) will run all classes and methods 
        // in parallel.  (First arg for classes, second arg for methods)
        JUnitCore.runClasses(new ParallelComputer(true, true), classes);
    }

    public static class ParallelTest1 {
        @Test
        public void test1a() {
            lookBusy(3000);
        }

        @Test
        public void test1b() {
            lookBusy(3000);
        }
    }

    public static class ParallelTest2 {
        @Test
        public void test2a() {
            lookBusy(3000);
        }

        @Test
        public void test2b() {
            lookBusy(3000);
        }
    }

    public static void lookBusy(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
            System.out.println("interrupted");
        }
    }
}

The above code will run in 3 seconds because all methods and classes are ran in parallel.

This will run in 6s (because all classes are in parallel). JUnitCore.runClasses(new ParallelComputer(true, false), classes);

This will also run in 6s (because all methods are in parallel). JUnitCore.runClasses(new ParallelComputer(false, true), classes);

like image 82
Andy Guibert Avatar answered Sep 29 '22 07:09

Andy Guibert


Yes, You can.

If you are using maven. You can take help of

maven-surefire-plugin

In Spring,

You can check this Link

<build>
    <plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.7.1</version>
        <configuration>
            <parallel>classes</parallel>
            <threadCount>5</threadCount>
        </configuration>
    </plugin>
    </plugins>
</build>

Solution 2: Junit4 provides parallel feature using ParallelComputer

like image 42
VeKe Avatar answered Sep 29 '22 07:09

VeKe