Upload
rafael-winterhalter
View
353
Download
2
Embed Size (px)
DESCRIPTION
Concurrency has become an increasingly important topic in the Java space. Nevertheless, most Java developers do not address concurrency in their unit tests. This talk shows how to and how not to test concurrent code and introduces Thread Weaver, a library for testing concurrent code.
Citation preview
Unit testingconcurrent code
public class FlawedList<T> extends ArrayList<T> { public boolean putIfAbsent(T object) { boolean absent = !super.contains(object); if (absent) { super.add(object); } return absent; }}
Implementing a broken unique list
@Testpublic void testPutIfAbsent() { FlawedList<String> list = new FlawedList<String>(); list.putIfAbsent("foo"); list.putIfAbsent("foo"); assertThat(list.size(), is(1)); }
JUnit
FlawedList<String> list = new FlawedList<String>();
@Test(threadPoolSize = 5, invocationCount = 20) public void testList() { list.putIfAbsent("foo"); assertThat(list.size(), is(1)); }
TestNG
TestNG with breakpoints
public class FlawedList<T> extends ArrayList<T> { public boolean putIfAbsent(T object) { boolean absent = !super.contains(object); if (absent) { super.add(object); } return absent; }}
FlawedList<String> list = new FlawedList<String>();
@Test(threadPoolSize = 5, invocationCount = 20) public void testList() { list.putIfAbsent("foo"); assertThat(list.size(), is(1)); }
public boolean putIfAbsent(T object) { boolean absent = !super.contains(object); if (absent) { super.add(object); } return absent; }
Testing with break points: first weaving
FlawedList["foo", "foo"]FlawedList["foo"]FlawedList[]
Testing with break points: second weaving
Thread 1Thread 2
Legend:
ThreadWeaver
absent
true
falsetrue
public class WeavedFlawedListTest { private FlawedList<String> list;
@ThreadedBefore public void before() { list = new FlawedList<String>(); }
@ThreadedMain public void mainThread() { list.putIfAbsent("foo"); } @ThreadedSecondary public void secondThread() { list.putIfAbsent("foo"); }
@ThreadedAfter public void after() { assertEquals(1, list.size()); } }
ThreadWeaver (https://code.google.com/p/thread-weaver)
Seamless JUnit integration
public class MyListTest {
@Test public void testFlawedList() { AnnotatedTestRunner runner = new AnnotatedTestRunner(); runner.runTests(getClass(), FlawedList.class); }
// put method with @Threaded<...> annotations here}
@Test public void testFlawedList() { AnnotatedTestRunner runner = new AnnotatedTestRunner(); runner.runTests(getClass(), FlawedList.class); }
How does it work?
Instrumented code:
public boolean putIfAbsent(T object) { Framework.considerBreakpoint(Thread.currentThread(), 0); boolean absent = !super.contains(object); Framework.considerBreakpoint(Thread.currentThread(), 1); if (absent) { Framework.considerBreakpoint(Thread.currentThread(), 2); super.add(object); } Framework.considerBreakpoint(Thread.currentThread(), 3); return absent; }
http://rafael.codes@rafaelcodes
http://www.kantega.nohttp://blogg.kantega.no
http://bytebuddy.nethttps://github.com/raphw/byte-buddy