|
This is a very simple and small (~250 LOC) library for writing concurrency tests with JUnit (tested with JUnit 4.10). There are 2 ways of using it: ConcurrentTestRunnerIf you want to run a test concurrently multiple times, just use the ConcurrentTestRunner. Optionally, the number of threads and a timeout can be specified either with @ConcurrentTest for all tests in a class or with @ConcurrentTestMethod for a specific test-method. By default, numThreads is set to 10 and timeout is set to 0, disabling the timeout. @RunWith(ConcurrentTestRunner.class)
public class ConcurrentTestRunnerTest {
@Test
public void testRun10TimesByDefault() {
System.out.println("This is going to be printed 10 times.");
}
@Test
@ConcurrentTestMethod(numThreads = 20, timeout = 100)
public void testRun20TimesByDefault() {
System.out.println("This is going to be printed 20 times and will abort after 100 ms.");
}
}ThreadConductorRuleIf you want to be specific, what should be executed in which threads in which order, you can use a ThreadConductorRule. It will generate an arbitrary amount of Threads for you, where arbitrary code can be run within in sequential order. public class ThreadConductorRuleTest {
@Rule
public ThreadConductorRule threadConductor = new ThreadConductorRule();
@Test
public void testThreadConductor() throws Throwable {
ConductedThread thread1 = threadConductor.createThread(new Runnable() {
@Override
public void run() {
System.out.println("First statement in thread 1.");
}
});
ConductedThread thread2 = threadConductor.createThread(new Runnable() {
@Override
public void run() {
System.out.println("Second statement in thread 2.");
}
});
thread1.continueThread(new Runnable() {
@Override
public void run() {
System.out.println("Third statement in thread 1.");
}
});
ConductedThread thread3 = threadConductor.createThread(new Runnable() {
@Override
public void run() {
System.out.println("Fourth statement in thread 3.");
}
});
thread2.continueThread(new Runnable() {
@Override
public void run() {
System.out.println("Fifth statement in thread 2.");
}
});
}
}More Features:Return Values for ConductedThreadpublic class ThreadConductorRuleWithReturnValuesTest {
@Rule
public ThreadConductorRule threadConductor = new ThreadConductorRule();
@Test
public void testThreadConductorWithReturnValues() throws Throwable {
final ConductedThread thread1 = threadConductor.createThread();
thread1.continueThread(new Runnable() {
@Override
public void run() {
thread1.setReturnValue(7);
thread1.setReturnValue("test return value");
}
});
assertEquals(7, thread1.getReturnValue(Integer.class).intValue());
assertEquals("test return value", thread1.getReturnValue(String.class));
}
}Exceptions passed from ConductedThread to main threadpublic class ThreadConductorRuleWithExceptionsTest {
@Rule
public ThreadConductorRule threadConductor = new ThreadConductorRule();
@Test(expected = AssertionError.class)
public void testThreadConductorWithAssertionInThread() throws Throwable {
threadConductor.createThread(new Runnable() {
@Override
public void run() {
fail();
}
});
}
}
|