A Rule to Test Them All (At Once)
May 23, 2013 | 2 min ReadUnit tests often stop being useful where concurrency is involved. A special case is thread safety which can be tested relatively easily with the use of a simple JUnit rule.
Suppose middle earth wants to keep track of the dragons that were slain over the centuries. The dragons are tracked in one list, and reports come in from different dwarfs, humans or elves. Sometimes, a dragon was reported slain falsely, so it needs to be removed.
A test for this list could look like this:
public class SlainDragonsTest {
private final SlainDragons uut = new SlainDragons();
@Test
public void shouldSafelyAddAndRemove() throws Exception {
uut.addSlain("Scatha");
uut.addSlain("Smaug");
uut.addSlain("Glaurung");
uut.removeSlain("Smaug");
assertThat(uut.getSlainDragons(), hasItem("Glaurung"));
assertThat(uut.getSlainDragons(), not(hasItem("Smaug")));
}
}
After a battle, lots of reports tend to come in at the same time, so the list has to work under stressful conditions without errors. So, we want the test to be executed simultaneously by a large number of threads. Each of the threads has to pass and the collective result decides on the JUnit report. For this purpose I wrote a “Manifold” class that converts the test to a load test.
@Rule public Manifold simultanousReports = new Manifold(200);
Internally, Manifold opens 200 threads and runs the test method simultaneously inside the thread. It waits for all of the threads to finish and fails with the first error it found. No further adjustment of the test methods is necessary. If you are interested, you can download the class Manifold here.
Happy dragon hunting!