Development Central

Bill Sorensen's software development blog

That's not TDD

I'm currently reading Pro ASP.NET MVC 4 as part of learning web development. So far it's been a good tutorial, but I take issue with the author's coverage of Test-Driven Development (TDD).

I applaud the coverage of unit testing, dependency injection, mocking, separation of concerns, and other best practices. It's the details that bother me.

In chapter 6, the author says he will follow the TDD approach in a unit test example. He starts out by writing the system under test and having it throw a NotImplementedException. Bzzt. Write the test first. There is a reason for this: the tests guide your design. You write the API you want to consume.

Next, he writes the unit tests. All of them. In TDD, you write one test, see it fail, write code to get it to pass, refactor, and then repeat. While there's no law that unit tests must be written in that fashion, changing the process means you're not doing TDD. If you don't want to do TDD, fine, but don't call it that.

Several of the tests violate the guideline of one logical assert per test. The only justification I can see is brevity. This comes at a cost: when the first assert fails, subsequent asserts are not run. In addition, messages have to be added to the asserts for clarity; it's much better to include this information in the test method name.

// These should be three separate test methods
Assert.AreEqual(5, TenDollarDiscount, "$10 discount is wrong");
Assert.AreEqual(95, HundredDollarDiscount, "$100 discount is wrong");
Assert.AreEqual(45, FiftyDollarDiscount, "$50 discount is wrong");

The author encourages use of the ExpectedExceptionAttribute. This is far too coarse-grained, and is one reason for avoiding MSTest (which the book also promotes).

I encourage everyone to go to the experts to learn TDD and unit testing. Two good sources are Test Driven Development: By Example and The Art of Unit Testing.

The book's coverage of dependency injection is incomplete as well; the authoritative work is Dependency Injection in .NET.

I'm being harsh for a book on ASP.NET MVC. If you're going to cover these topics in detail, though, please get the details right.

Disfunctional

A coworker and I spent a total of at least 8 man-hours this week tracing down one threading bug. The original author was locking access to shared state, and got it almost right.

Writing thread-safe code that uses global mutable state is hard. It's much easier to avoid the problem entirely.

Functional programming emphasizes pure functions (the same inputs will always give the same output, with no side effects) and immutable types. If you write your code in that style, thread safety comes naturally.

Regardless of programming language, consider a more functional approach. Your future self will thank me.

For a good book on the subject, try Real-World Functional Programming: With Examples in F# and C#.