C. Keith Ray

C. Keith Ray writes about and develops software in multiple platforms and languages, including iOS® and Macintosh®.
Keith's Résumé (pdf)

Wednesday, March 5, 2014

Microblogged on Twitter

By the way, I recently micro-blogged a series of "straw-man" arguments against, and rebuttals for, unit-testing and TDD. Here they are somewhat expanded. Rebuttals are italic. 

I am NOT making up these straw-men arguments. I’ve even heard them from people who should, 14 years after Extreme Programming Explained was published, have some understanding of incremental design and development, who should know both the differences and similarities between TDD and unit testing, and how refactoring fits into both small and big design activities.

1. straw-man: OO means you can't know what modified something's state.

That sounds like a global var bug. Objects can guard their state. Most people could learn a bit more about designing non-mutable classes, but OO doesn’t prevent you from knowing an object’s state.

2. straw-man: Always-passing tests are useless. 

Yes, tautological tests are useless. Don't do that. You learn something when a rarely-failing unit test fails: something unexpected happened! Either some code (or data) has changed and it now violates a test’s description of how that code (or data) is supposed to work, or the programmers forgot to update their tests. If a test that has been passing for 10 months suddenly fails, you know something is wrong. The worser condition is that no problem is detected until 20 months have passed, and you have to trace changes back to 10-month old code to find out what code-change caused the problem.

Tests that fail frequently or seemingly randomly, indicate a “people” problem: members of the team don’t understand the requirements, or requirements keep changing due to activity outside of the team, or coding or testing not done well and better training is needed.

3. straw-man: without testing-hooks in code, you can't do white-box tests.

Try mock objects.

4. straw-man: to test a for-loop, you need as many tests as there are iterations in the loop. 

Heard of boundary testing? See my Testing on the Toilet entry.

5. straw-man: changing code requires changing tests. 

This isn't a big burden if DRY (“Don’t Repeat Yourself”) is applied to both code & tests. (See also “Once and Only Once.)

5. straw-man: you can't have nice OO because TDD tests are "procedural". 

So not having no tests is required for nice OO?

6. straw-man: TDDing classes = bad design, because incrementally designing a class or classes while writing tests can’t be done well.  And, refactoring the structure of the code (to improve the design) is can’t be done, either.

Really? refactoring is supported by TDD-tests. Do well-designed classes pop out of your head fully-formed?

6. straw-man: when implementing features one-at-a-time, user experience is a  mess.

Before BDD, did you design entire UX in one second? It was incremental then, too.

7. straw-man: the object's state-space is big number (like 2**32) so we can't write enough unit tests, so don't even try.

Heard of boundary testing? See my Testing on the Toilet entry.


  1. Keith, I couldn't find your Boundary Testing ToTT article in the Google Testing blog (plenty of familiar names there). Do you have a current link?

    1. All the links in this post were accidentally "lost" and I will add them back into the post. For now, here's my "Too Many Tests" ToTT: http://googletesting.blogspot.com/2008/02/in-movie-amadeus-austrian-emperor.html and here's Mike Bland's "Finding the Worm Before the Apple Has Shipped" http://autotestcentral.com/finding-the-worm-before-the-apple-has-shipped