Running concurrently can lead to unexpected results. For instance, I just discovered, that while my Test suite with 200 tests pass when executed one by one, it fails for concurrent execution, I dug that and it wasn't a thread safety problem, but a test depending on another one, which is a bad thing and I could solve the problem.
Mycila work on JUnit ConcurrentJunitRunner and ConcurrentSuite is very interesting. The article seems a little outdated compared to the latest GA release, in my examples I will show the updated usage.
Annotating a test class like the following will cause to execute test methods concurrently, with a concurrency level of 6:
import com.mycila.junit.concurrent.ConcurrentJunitRunner;
import com.mycila.junit.concurrent.Concurrency;
@RunWith(ConcurrentJunitRunner.class)
@Concurrency(6)
public final class ATest {
...
You can also run all the test classes concurrently:
import com.mycila.junit.concurrent.ConcurrentSuiteRunner;
@RunWith(ConcurrentSuiteRunner.class)
@Suite.SuiteClasses({ATest.class, ATest2.class, ATest3.class})
public class MySuite {
}
The Maven dependency is:
<dependency>
<groupId>com.mycila</groupId>
<artifactId>mycila-junit</artifactId>
<version>1.4.ga</version>
</dependency>
I am currently investigating how to run methods multiple times and concurrently with this package. It may be possible already, if anyone has an example let me know, below my homebrewed solution.
@Test
public final void runConcurrentMethod() throws InterruptedException {
ExecutorService exec = Executors.newFixedThreadPool(16);
for (int i = 0; i < 10000; i++) {
exec.execute(new Runnable() {
@Override
public void run() {
concurrentMethod();
}
});
}
exec.shutdown();
exec.awaitTermination(50, TimeUnit.SECONDS);
}
private void concurrentMethod() {
//do and assert something
}
As others noted, is true that you can never be sure whether a concurrency bug would show up or not, but with ten of thousands, or hundred of thousands executions with a concurrency of, say 16, statistics is on your side.