I have a testing background and it feels very natural to me to approach a programming task by identifying all interesting inputs and edge cases and writing down the expected outputs and behavior. Is this method useful when test-driving code?

It depends. Sometimes when people do TDD, they’re too eager to jump into the first test and spend too little time thinking about the problem and the design. In “Test-driven Development by Example”, Kent Beck writes about both keeping a list of upcoming cases/tests and the fact that designing things on paper before writing the tests may be a good idea as long as you’re aware of the gap between decisions and feedback. In this light, spending time upfront thinking about interesting cases is a good idea.

However, throwing a table, of let’s say 30 cases, at some yet unwritten code isn’t very helpful either. There will be no test-driving and the process of making all these 30 tests pass at once will be an exercise in blind coding. There will be no steady progress and no safety net. The obvious thing to do is to turn these 30 tests into a prioritized list, and taking the tests on one by one. At this point it may be useful to remember the test order:

  1. Degenerate case
  2. One or a few happy path tests
  3. Tests that provide new information or knowledge
  4. Error handling and negative tests
Book References
Read more about this topic in Developer Testing: Building Quality into Software:

  • Chapter 14: Test-driven Development—Classic Style, pages 191 and 204