
How I Started TDD - r11t
http://blog.extracheese.org/2009/11/how_i_started_tdd.html
======
tjpick
gah! but all those steps make the whole process harder than just thinking hard
and writing down the correct function to start with. Or to write several test
cases to start with (because you know many of the expected outputs up front)
and writing a single function that passes them all.

TDD should make the process EASIER and MORE efficient.

>>> This isn't a perfect example of TDD, but that's not the point.

Illustrating a process by applying it to a problem that doesn't need it is
surely the wrong way to go about it. Unfortunately "the point" is mostly
dwarfed by the imperfect example.

~~~
garybernhardt
This post was aimed at the person who is interested in TDD, but hasn't had
their first big insight into how it works. It's about "do the simplest thing",
not about a full TDD process to build a working production system. As I said
to someone else in this thread, such a blog post would be huge. No one would
read it. We wouldn't be here talking about it. :)

------
sync
That last step is quite a leap from the previous 6.

~~~
wooby
I agree - this TDD-koan stuff really turns me off. What's preventing the
author from just writing fibonacci as an infinite series of tests, and an
infinitely long switch statement?

What the article doesn't mention is that full coverage on a function taking
all positive integers is impossible unless you're comfortable making some
assumptions about the behavior of your program.

The 'leap of faith' here is induction and the transition from simple
testability to recursive implementation is huge, and left basically
unexplained.

I personally think TDD is a great tool and an awesome way to write code. But
it doesn't have to be this mysterious; I just think a function like fib is not
a good way to show the benefits.

~~~
garybernhardt
The thing preventing infinite implementation is a combination of (1) the rules
of simple design and (2) the definition of "simple". I write about those in
the follow-up to this post:
<http://blog.extracheese.org/2009/11/the_limits_of_tdd.html>

I've said this several times across several forums since publishing this post,
but my goal was to write a very brief example of "doing the simplest thing".
It's not about doing the entire TDD process on a real-life software problem,
because that post would be so long that no one would read it! :) I don't think
TDD can't be adequately demystified in any short example.

~~~
memetichazard
I'd read it! Well, if I happened to stumble across it anyways. Might I suggest
something like, say, Sudoku? :P

Not having done any TDD, I'm feeling the same way as most of the responders
here so far, and I think the problem is that Fibonacci is too trivial.

Although, I can come up with something even more trivial - suppose you wanted
to TDD a "Hello World" program. Would you start your first test by verifying
that the first letter of the output is 'H', and implement as your simplest
implementation something that prints only 'H'?

I'm not sure how the design process works under TDD, so, here's a couple of
questions.

Suppose you already have some implementation that represents a tic-tac-toe
board and you need to determine whether a winning position exists on the
board.

Do you begin by working on the X_Wins() method, or do you start looking at a
smaller method, say, Count_Xs_in_Row(row)?

If the latter, do you do the same thing for this method as for Fibonacci?
(first iteration: return 0. second iteration: return 1 if the first cell is X,
else 0. 3rd iteration: return 2 if X, else 1 if Y, else 0. Iteration 3: Truth
table. Iteration 4: refactored into a counter with incremented for each X
found.)

If the former, well, basically the same question. Do you begin by checking for
one row of X's, then eventually expand to checking all 6 row/column
combinations, then refactor out the method? (I initially thought this would
require many more iterations... but it seems 7 test cases are enough)

Well, in any case, Tic-tac-toe would be quite a bit longer, but it would
probably be much better for introducing TDD. Explanations aren't necessarily
required - just seeing all the different iterations of the code would be
fairly instructive.

Perhaps use Etherpad for their timeline capabilities?

~~~
garybernhardt
I'll think about it. With the awful response from Reddit [1], I'm not sure
that I want to make another go at it. :) We'll see.

To respond to your example, I'd almost certainly go with something like your
Count_Xs_in_Row path, or some similar subset of the problem. I'd probably
first drive out the "win" concept by saying "if there's a row full of Xs, X
wins; if a row full of Os, O wins." I don't actually need to be able to count
rows for that; I can pass something fake in (probably a stub). Once I'd done
that, I'd drive out the row counting, possibly backporting that into the "win"
tests, but probably leaving them totally isolated.

In this example, the key insight is that the concept of winning (a full row)
can be independent of the process of counting rows. The tests would push you
toward that separation naturally, because it would be too hard to think about
testing the "X wins" directly based upon a full board.

This is still a bit overwrought, as it's still a toy example. Toy examples
make TDD sound silly, which is a big part of its perception problem. I still
don't know how to fix that other than pairing with a person and/or talking
directly to them in person for a couple hours. :(

[1]
[http://www.reddit.com/r/programming/comments/a2yhe/im_not_su...](http://www.reddit.com/r/programming/comments/a2yhe/im_not_sure_if_this_is_an_example_of_how_tdd/)

