Friday, November 16, 2007

Does "Test After" Work For You?

"Why not write a test for this?"
"Why should I, it works..."

The idea of Test-After Development is to write a set of automated white-box tests after writing your production code. Since probably every CS student in the world has learned that unit tests are a good idea, you'd expect unit testing to be an industry state standard for quite a while now. Interestingly the idea of automated unit and integration test is lately becoming more popular due to the widespread use of Test-Driven Development.

So why do we need Test-Driven Development to be able to efficiently write automated unit tests?

  • If you write your code first and don't think about how to test the code, the code will not be testable. Thus testing becomes expensive and frustrating. Test-Driven Development will guide your software design by the old mantra of "how-do-I-want-to-use-this-class", leading to a highly decoupled design.

  • When you write your tests, you'll discover a lot of errors. But instead of the red bar in Test-Driven Development, which you expect, the red bar in Test-After Development is the demotivating sword of reality.

  • The most important reason why I have never seen Test-After Development work, is that developers just don't believe in errors once they wrote the code. This seems to be an eternal wisdom of software development psychology: once the code works, why bother testing it? Let's just implement the next feature.


  1. Sometimes, the test after are the only tests that are written. Though, sometimes its not long after.
    I've noticed a few variations on the test after phenomena:
    - A manager shows up and says that x amount of coverage is needed (and little if no tests exist). This is really the worst case. Because the tests that are written will be written to pass. So, they do little more than demonstrate behavior.
    - A developer is learning TDD but, is having a hard time. So, tests tend to be written shortly after a class is written. Its still better than the previous because the developer is actually trying to break the class. These tests can stimulate refactoring but, do little to affect design.

  2. In some respects the tests have the potential to become a good communication tool, as they, in theory, communicate intent. Standards such as naming the test meaningfully like "CanGetObjectCollectionFromFactory" or "ShouldHaveIDEqualThirteen" are such examples.

    TTD is hard, because it's like drawing a picture in reverse where you don't draw shapes, instead your pencils create the boundaries of the empty space. Afther the empty space have been defined, you have your picture. Think about it, it's not even like a figure drawing upside down.

    Rocky Lhotka has an interesting take on TTD: it helps you think through your code, but is very incomplete and cuts you off from using the development suite tools effectively.

  3. Sensei,

    I like your metaphor of drawing a painting. I read in a beginners handbook for drawing that you should "look at the space between objects" when drawing outlines, since this will stop the effect of your brain "interfering" with what you see by telling you what you expect to see. This is exactly one of the things TDD does for me.

    TDD is incomplete, but a lot more complete than not having automated tests at all levels of the application, which seems to be a current industry practice.

    I don't understand what you mean by "cuts you off from using the development suite tools effectively", have you ever tried TDDing with eclipse and java?

    Thanks for leaving your thoughts

  4. Ich stamme aus "Microsoft" Entwickelung- sorry my German is really bad. My mother-in-law is from Passau, and we still have relatives in Deustchland.

    Anyhow, to elucidate, I TTD with NUnit, Visual Studio and flirted with Resharper from Jetbrains. My comment concerning being cut off from tools stems from Rocky Lhotka (CSLA.Net) comments. His premise is if you TTD from scratch you should have no object or object collection, just the code for the test. At this you can not avail yourself of Intellisense as you do not even have the namespace or domain. Hence any of the refactor macros or assistance that Visual Studio can provide out of the box is unusable.

    Resharper is a product built to bridge this gap as it will "abstract" the objects from your test and allow you create your interfaces, abstract objects, what have you. This places you places you in very productive mode, as you truly think of you tests, call up a refactoring template and create you code / objects from the items you have first added to the test. In a sense it truly allows you to only develop what the test requires.

    I am currently evangelizing my direct reports with TDD, and one poor fellow is about to start tomorrow, he just doesn't know it yet. Yes, I am mean boss but am lucky as my team enjoys a challenge. Myself I have used it effectively in several situations where it have greatly focused my efforts and provided a great communication tool. Sort of using code to describe and document code.

  5. Between me and my husband we've owned more MP3 players over the years than I can count, including Sansas, iRivers, iPods (classic & touch), the Ibiza Rhapsody, etc. But, the last few years I've settled down to one line of players. Why? Because I was happy to discover how well-designed and fun to use the underappreciated (and widely mocked) Zunes are.