unit testing concurrent code
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.TRANSCRIPT
![Page 1: Unit testing concurrent code](https://reader036.vdocument.in/reader036/viewer/2022082512/54cf3a224a79597a6d8b460b/html5/thumbnails/1.jpg)
Unit testingconcurrent code
![Page 2: Unit testing concurrent code](https://reader036.vdocument.in/reader036/viewer/2022082512/54cf3a224a79597a6d8b460b/html5/thumbnails/2.jpg)
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
![Page 3: Unit testing concurrent code](https://reader036.vdocument.in/reader036/viewer/2022082512/54cf3a224a79597a6d8b460b/html5/thumbnails/3.jpg)
@Testpublic void testPutIfAbsent() { FlawedList<String> list = new FlawedList<String>(); list.putIfAbsent("foo"); list.putIfAbsent("foo"); assertThat(list.size(), is(1)); }
JUnit
![Page 4: Unit testing concurrent code](https://reader036.vdocument.in/reader036/viewer/2022082512/54cf3a224a79597a6d8b460b/html5/thumbnails/4.jpg)
FlawedList<String> list = new FlawedList<String>();
@Test(threadPoolSize = 5, invocationCount = 20) public void testList() { list.putIfAbsent("foo"); assertThat(list.size(), is(1)); }
TestNG
![Page 5: Unit testing concurrent code](https://reader036.vdocument.in/reader036/viewer/2022082512/54cf3a224a79597a6d8b460b/html5/thumbnails/5.jpg)
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)); }
![Page 6: Unit testing concurrent code](https://reader036.vdocument.in/reader036/viewer/2022082512/54cf3a224a79597a6d8b460b/html5/thumbnails/6.jpg)
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
![Page 7: Unit testing concurrent code](https://reader036.vdocument.in/reader036/viewer/2022082512/54cf3a224a79597a6d8b460b/html5/thumbnails/7.jpg)
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)
![Page 8: Unit testing concurrent code](https://reader036.vdocument.in/reader036/viewer/2022082512/54cf3a224a79597a6d8b460b/html5/thumbnails/8.jpg)
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}
![Page 9: Unit testing concurrent code](https://reader036.vdocument.in/reader036/viewer/2022082512/54cf3a224a79597a6d8b460b/html5/thumbnails/9.jpg)
@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; }
![Page 10: Unit testing concurrent code](https://reader036.vdocument.in/reader036/viewer/2022082512/54cf3a224a79597a6d8b460b/html5/thumbnails/10.jpg)
http://rafael.codes@rafaelcodes
http://www.kantega.nohttp://blogg.kantega.no
http://bytebuddy.nethttps://github.com/raphw/byte-buddy