Hi Ed,
I do have a bone to pick with the tutorial (or maybe I don't understand
TDD/BDD yet). In the stack example, I cringe with horror when I see them
setting a method that just returns "true" simply to get a test to pass.
That grates on me, because I *know* I'm actually going to have to write
the real code eventually. It seems like a waste of time to do the
nitty-gritty "add a test to the spec/add a trivial fix to the code" cycle.
I don't look at this as "add a test to the spec/add a trivial fix to
the code" but instead as "add a test to the spec/do the simplest thing
that could possibly work to get the tests to pass", and I find
substantial value in this approach.
A few weeks ago I was doing BDD using RSpec and Francis Hwang's MockFS
library (which mocks the file system). I needed to add a method to
MockFS to mock File#size. So I added a spec that called File#size,
and ran it. As expected, I got some error about File#size not found.
I looked through the MockFS code to see where this error came from,
and I saw that MockFS had an array of symbols which were the names of
the methods that it mocked. :size wasn't in this array, which caused
the error. Looking at the MockFS code, I *knew* that I needed to do
two things: add :size to the array, and also implement the method that
mocked File#size. I remember being strongly tempted to do both these
changes before re-running the spec. But since I got the error because
:size wasn't in the array, simply adding :size to the array was the
simplest thing that could possibly work. So I did that, and re-ran
the spec, *knowing* that I was going to get a NoMethodError. But
instead, ALL MY TESTS PASSED. I was quite surprised. Investigating
what had happened, I discovered that Francis implements the mock files
as StringIO objects, so StringIO#size got called, which returned the
size of the string/file, which was correct, so all the tests passed.
(Duck Typing in action).
If I hadn't forced myself to try the simplest thing that could
possibly work, I would have had to implement (and debug) a File#size
mock method. This would have added unnecessary complexity to the
system. Worse, my experience is that once code gets implemented and
debugged, it rarely gets removed. So that code probably would have to
be maintained forever.
By forcing myself to always do the simplest thing that could possibly
work, I find that every day or two I come across a situation just like
this one, where a solution that I would have gladly bet serious money
that it was too simple to really work, actually does work. In
addition, every hour or two I find a solution that I thought might be
too simple to really work, that does work. Before I was doing BDD/TDD
I very rarely came up with simple solutions like this. The cumulative
effect is that my code is noticeably simpler and cleaner, and I find
this to be one of the major benefits I get from BDD/TDD.
Wayne