Peter Miller

Musings on Technology and Programming
in

Why Test Driven Development is a Hard Sell

A Good Presentation

Two weekends I went to a San Diego Dot Net User Group meeting that featured two presentations by a speaker Jeffery Palermo about ASP.NET MVC and more specifically about how it and other tools enable Test Driven Development (TDD) and separation of concerns.

Jeff was a great speaker and his presentation was inspiring. He extolled the virtues of Onion Architecture, an architecture that through the use of interfaces and dependency injection, enables you to isolate your core business logic away from the infrastructure code that enables interaction with that logic.

Beyond isolating your core business logic, which is almost tautologically a “good thing”, Onion Architecture makes it easy to follow the principles of TDD. For Jeff’s purposes, TDD was defined as accompanying the check-in of any new code with corresponding and covering unit tests.

Jeff also briefly covered the technology that makes this all possible: NUnit for unit tests, NHibernate for a decoupled, testable data access layer, StructureMap for dependency injection, Rhino.Mocks for enhanced unit testing and ASP.NET MVC for a testable web UI layer.

Jeff was persuasive in describing the benefits of the Onion Architecture and TDD, but I was left wondering if his point was too abstract. All other things equal, I think it is a no brainer to prefer a set of code with a bunch of unit tests around a flexible architecture over a set of code with no tests and an architecture that actively resists changes.

However, when this statement of abstract preference intersects with the real projects I’ve been involved in, the picture becomes much fuzzier. In order to keep this somewhat short, I’ll stick with discussing just TDD for now.

What Makes Code Better?

A core principle of TDD is that code with unit test coverage is better than code without unit test coverage. Or as it sometimes phrased, code without unit tests is “legacy”, i.e. bad code. These kinds of statements are fun to debate, but ultimately good/better/quality in code itself is a subjective judgment that I’m unlikely to resolve on this blog. More apropos is to ask, does TDD allow you to better produce software that solves its users’ problems?

TDD = Better User Satisfaction and Experience?

If you develop software for a living, you certainly care about the quality of your code, but more importantly you should care about how your end product meets your users’ needs. Is there any evidence, beyond anecdotal reports, that applications developed using TDD have more satisfied users? I haven’t seen any (feel free to correct me with relevant links), and my intuition is that the answer is no.

TDD enables you to automate your testing and heavily suggests testable architectures to enable TDD. Both of these can be nice, but it is not like software without TDD goes out untested and with no architectural planning. Whether it is ad-hoc developer tests and/or formalized Quality Assurance testing, only a fool deploys code that has not been tested at all. And just as you can have QA testing that is inadequate, unit test coverage is only as useful as the tests providing the coverage.

More importantly then just defect control, does TDD make you better understand your users’ needs or think of ways to address them? The users of your application are unlikely to care if you used TDD or any other technique; they want results. With that in mind, it is clear that TDD is not a silver bullet.

Department of Fairness

In fairness to Jeff and other advocates of TDD, I don’t think most of them would claim TDD to be a silver bullet, but rather one technique in the greater ecology of agile development, a discipline that leads to (not predicates) successful outcomes. Granting this, it still leaves unanswered the question of whether or not this discipline leads to more successful outcomes.

Premature Optimization?

Having been on many successful projects that don’t use TDD, my impression is that TDD is a form of premature optimization. Meaning that if I had a highly skilled, highly competent team that consistently delivered quality software, I’d experiment with it and see if we got even better. However, in my experience, people trump process and procedures. More specifically, a team of bright, creative and dedicated individuals with good management will produce quality software no matter what techniques or processes it is using. Conversely, if your team is in trouble, TDD is just a way to avoid addressing the core issues or deficiencies amongst your team.

With all that said, I plan to spend a lot more time investigating TDD and the technologies Jeff mentioned because I think they have good potential to help me deliver more quality software. I do that keeping in mind that as software developers we are apt to put false hope in finding technology solutions for every problem we encounter.

Comments

Jeffrey Palermo said:

I'm glad you enjoyed the presentation.

". . . a team of bright, creative and dedicated individuals with good management will produce quality software no matter what techniques or processes it is using"

A team of bright people will produce quality software _because_ of the mature techniques they have developed/adopted.

I'm not a cheerleader for TDD.  I don't have any incentive to promote it.  It's only one piece of a complex web of practices that helps us deliver software.  

# October 6, 2008 6:38 PM

pmiller said:

Thanks for the comment Jeffery. I think we end up at the same place, I just chose a much longer way to say it. I look forward to seeing your ASP.NET MVC book released. Thanks again for a thought provoking presentation.

# October 6, 2008 7:02 PM

Joe Brinkman said:

@Peter - I don't believe most proponents of TDD view the tests as the end goal.  In agile methodologies, the tests are merely a means to provide the confidence needed to refactor code without being excessively worried about introducing breaking changes.  Almost every program will spend the majority of its lifecycle in the maintenance mode.  New features are added, old features are enhanced and bugs are fixed.  During this period having a complete set of unit tests allows you to make the needed changes and to know if the new changes have broken any of the old functionality.

# October 7, 2008 9:44 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)