Design for testability

I just found Michael Feathersrant about designing for testability. I couldn’t agree more with his sentiment!

A couple of years ago I worked with a team that had exactly the problem Michael describes. Many of the classes were nearly impossible to instantiate in a test harness, and many of their methods couldn’t be tested without dire consequences for the development environment. Refactoring in the subsystems that contained these classes was also impossible, because of the unpredictable side-effects incurred by doing almost any method call. In the end, after months of frustration, we decided to very carefully and incrementally throw away those classes and replace them with something testable. In fact, that large-scale refactoring was never finished (due to circumstances outside the team’s control), but the improving code definitely “felt” better.

I believe Michael has hit on the perfect first-pass measure for code quality: how long does it take to write a unit test for a randomly chosen method of a randomly chosen class? Until the answer is under 5 minutes throughout a codebase, the design isn’t testable.

And once that measure is achieved, something remarkable happens: the team is no longer afraid to work with that code. The code itself no longer inhibits its own use in the development of new stories. It’s as if the code is somehow a better place to work. So here’s an intriguing analogy with the lean manufacturing world: If the code is the gemba (the workplace in lean thinking), making it testable promotes the flow of customer value through it. Kaizen!

3 thoughts on “Design for testability

  1. When I was reading “Lean Thinking” by Womack a while ago, the source code as the production floor jumped out at me for the first time. It makes a very good analogy when comparing software development to traditional production systems.

    It also explains why the kaikaku events (radical improvements) are harder for consultants doing software improvements vs manufacturing improvements. You can walk into a factory and /see/ the machines at work and discover waste. Its obvious where to start. Because the waste inherent in the source code (eg your example; how hard is it to develop tests) is harder to identify, its less obvious where to start the improvement programme. You are really forced to start with kaizen (continuous incremental improvement) until an understanding of the code is reached.

    Basically: refactoring = kaizen.


  2. Hi Julian,
    I agree with you – the analogy between the gemba and the codebase is striking, and potentially very powerful (the Agile NW group also discussed it at last week’s meeting). And I agree that the ‘invisibility’ of the code makes it hard to engineer the drama of kaikaku events.

    Here are some kaikaku activities I’ve been able to do (depending on the maturity – or otherwise – of the shop in question):

    ‘release’ the current code

    install the code into a CM repository

    get the build automated

    get the build time under an hour

    get just one test running every hour

    run a linter to identify unused code, and then remove it all

    run a dependency checker to identify loops, and then collapse each loop into a single module/package

    All except the last can create positive shockwaves…

  3. Pingback: if… « silk and spinach

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s