Sunday, September 15, 2013

TDD and multithreaded code

I recently watched a video of a talk by Venkat Subramaniam called "Test Driving and Unit Testing Thread Safety". http://www.agilealliance.org/resources/learning-center/test-driving-and-unit-testing-thread-safety

My first understanding of the title of the talk was that Venkat was going to describe a novel way to test code for thread safety. That understanding makes sense if you think of unit testing as a way to measure & ensure the quality of code.

However, I keep having to remind myself that TDD is not primarily a testing activity; quality assurance is not its primary goal. The primary purpose of TDD is design - to help you write well-designed code. That works because you can't test things in isolation if coupling is high.

Any time you're doing TDD and have code you don't know how to test in isolation, you have 3 options:
  • Don't test it.
  • Test it in context, in an integration test / manual testing / etc.
  • Refactor.
That last one is the gift TDD offers, and that's what Venkat was recommending in his presentation.

As I was watching Venkat code, I realized that what he was creating looked very familiar. I went back and found this blog post from 9 years ago: http://blogs.msdn.com/b/jaybaz_ms/archive/2004/05/06/127480.aspx. What's interesting to me here is that we came up with that code without doing TDD. We were only coding for fun, and we didn't understand TDD at the time. We just refactored mercilessly and that's what we ended up with.

I've also been reading Arlo Belshee's blog. He talks about mocks as a code smell, and the pattern of using simulators instead of mocks for external dependencies.

Thinking about Venkat's talk, Arlo's blog, and my old blog post, I decided to attack this problem again as a kind of kata. Specifically, I wanted to practice some ideas I've been studying recently:

  • Strict RED/GREEN/REFACTOR
  • Work Tiny.
  • NCrunch.
  • Letting TDD drive the design.
  • Treating mocks as an invitation to develop multiple useful implementations
Problem statement

Write a threadsafe counter. It supplies sequential integers to callers from multiple threads.

That is, make this threadsafe:

    class Counter
    {
        int i = 0;
        internal int GetValue()
        {
            return i++;
        }
    }

No comments: