More testing code than production code is typical, but don’t let that stop you

Ian Cooper recently wrote about the Ratio of test code to production code.  Ian is saying that he's routinely seeing a 1:1 or even 1.5:1 ratio of test code to production code.  From my experience with TDD, that's about normal.  Some kinds of code will go even higher.  For example, any kind of significant recursive functionality will make the ratio go throught the roof (a Visitor/Composite pattern combo is central to StoryTeller.  That jacks up the test code LOC relative to the real code LOC significantly).

All I want to add to Ian's post is that that number should not discourage newcomers to TDD.  All those lines of code are not created equal.  Unit test code does not take anywhere near the same amount of concentration or care as production code.  I say that mainly because unit test code is composed almost entirely of stand alone methods.  They don't interrelate or interract with each other.  The responsibility of a unit test is almost always the same:  setup data, do something, check the results.  The hardest thing about coding is deciding what to code, not the mechanical act of typing.  The hard part of writing a unit test is deciding what the real code is supposed to be doing , then codifying that specification in the unit test.  Since you'd be doing that specification work in your own head or a document anyway, all you've added is the mechanical work to type it out in a unit test method.

TDD is cost effective when and if the effort you put into writing the tests is less than the corresponding effort would have been for the manual unit testing and additional debugging that you dodge by having comprehensive unit test coverage.  Add in the hard to quantify advantage from the qualities of orthogonality that TDD all but requires (testability design is mostly about creating orthogonality between the pieces).  Plus, if you're good, time spent TDD is also time spent doing design in the small and hopefully creating a useful and human readable set of documentation about the fine grained details of the code.
 

And while I'm thinking about it, the whole "Who tests the tests" issue?

A.)  Keep your unit tests as simple, concise, and readable as possible to help catch problems by inspection

B.)  Just pay attention to what you're doing

C.)  What Phil Haack said in the link above about the code testing the tests and vice versa.  I find most unit test bugs when the test fails and the code seems perfectly right.

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Test Driven Development. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.illede.net rüya tabiri

    thank You.

  • http://www.xoobie.com.au Xoobie online auctions

    Three words:

    testing, testing, testing

  • http://www.portraitkingdom.com photo oil painting

    Thank you for sharing this information to us. I know most coders have experienced this but only very few have put their thoughts into writing.

  • http://www.factoryfast.com.au gifts

    This is probably an issue with all different types of coding / languages, and is probably not specific to a certain type. While some people may swear blindly that their preferred language results in less test code, I don’t think that’s entirely fair – especially since some languages are made for only basic things, are are being used as such. If you had to use such a language to do something else, you would probably run into serious problems. The secret, for me, is the right tool for the right job. In other words, code in the right language for the specific job that the language caters for. It makes perfect sense to me. The whole debate of ‘which language is better’ is, in my opinion, a whole lot of pointless drivel.

  • http://codebetter.com/blogs/jeremy.miller jmiller

    To Martin’s point about helper classes to set up domain object graphs –>

    http://www.martinfowler.com/bliki/ObjectMother.html

    ObjectMother can help bring down the mechanical cost of writing some unit tests and improve the signal to noise ratio of your unit tests.

  • http://community.ative.dk/blogs/ Martin Jul

    I often see twice as much unit test code as production code (this was roughly the ratio for a recent mainframe migration we did). Then add the acceptance tests on top and you have even more test code.

    On the other hand, I am currently helping a new team get a handle on their quality and they have much less UT code than production code. Needless to say, the “production code” isn’t quite production ready in terms of quality, so I am helping introduce more upfront, automated testing.

    One interesting point here is that a lot of the ground work is to introduce Equals methods on the domain objects so that tests will be simple and short, this being a prerequisite for convincing people to actually write the tests. I have also found that creating some proper factory classes to produce semantically meaningful domain object graphs are quite a boon when it comes to producing simple tests. It is so much easier to CompanyFactory.CreateMultiNationalConglomerate() than to add hundreds of lines setup code in each test that make it hard to see the intention of the test.

  • http://braincells2pixels.net rams

    and remember,
    D) Your software is only as good as the tests you write. Better tests, better software.