DEV Community


Discussion on: Solve this simple problem with TDD

michelemauro profile image

While reading and writing the other comments, something felt missing... then it dawned on me!

@delbetu , are we answering to your question?

I assumed that your question was "I had a hard time coming up with the tests for this problem". And approached the thing writing some tests. That led me to a suboptimal solution (but I can improve it, I have tests now!)

I think @jonsullivandev thought your question meant "I had a hard time solving this problem" and gave you a correct solution, proving it beyond every (well, almost) conceivable test.

Which one was it, @delbetu ?

(not that I mind the interesting discussion that came out of this...)

delbetu profile image
M Bellucci Author

"I had a hard time coming up with the tests for this problem" --> this is partially correct.
I was able to get a set of test cases.
I wasn't able to reach a solution through the application of micro cycles (red-green-refactor) based on those tests.

The point is "Does TDD work?"

michelemauro profile image

There is only one answer, of course: "It depends".

It depends on what you mean for "work".

TDD has a proven track of "working" in helping produce software that exibits less bugs, that it is closer to the specification encoded by the tests (that may or may not be the desidered one, but that's another story), and that is easier to debug. And that, at least locally, is better designed.

Things get much more blurred when you have:

  • non-functional specification that may not be testable without costly or impossible setup (i.e. it's difficoult to write a test for "must not exceed 50% CPU on the target hardware"). These situations require prototyping or something else.
  • correctness requirements that must be upholded in every concievable, and a few unconcievable, cases; Jon's approach covers exactly that (or at least part of it). These situations require formal methods.
  • a situation when "fiddling" is required (as Uncle Bob puts it); that is where a human estetic acceptance is required (you can't test for "it looks good") or when interacting with an external, poorly specified interface. These situations require experimentation.
  • to accomodate for unexpected or unforseen (at the moment of writing) architectural requirements (will the same code work for 100x the traffic? will you design the same if it is called 10k times per second instead of 10?). These situation require a wider vision and a cost/risk evaluation.
  • probably other situations that I can't think of right now.

So, TDD "works"... in every context where it works (sorry). That however covers quite a lot of possible programming problems. There undoubtedly are contexts in which TDD is not a perfect fit or does not work at all, and other tecniques must supplement or substitute it.