On Sat, Apr 29, 2006 at 05:22:15PM +0100, Kerry B. wrote:
} On 29 Apr 2006, at 3:42 pm, Gregory S. wrote:
You missed an attribution here. I did not write the following two lines.
} >} If you use test-driven development, there shouldn’t be any code
} >} that isn’t exercised by a test.
}
} >That is a common misconception. Suppose you have a single method
with
} >four code paths through it. It is called by another method with four
} >code paths through it. That is called by a method with four code
paths
} >through it. To test it exhaustively, you must write 64 (444)
tests.
}
} Surely the issue of type checking only comes up at the interfaces
} where methods are called?
Not necessarily. That was just an example. Consider the following:
class Foo
attr_accessor :bar
def do_something_with_a_string(arg)
fail ‘arg is not a string!’ unless String === arg
return bar.do_something_else(arg)
end
end
Foo#do_something_with_a_string makes sure that its argument is a string,
but what type is bar? And what is returned by do_something_else? You can
decide to implement your own attribute mutators that enforce type
instead
of using attr_accessor, but that gives up much of the power of Ruby.
After
all, the point of duck typing is that you don’t care an object’s type,
just its capabilities.
} You may have 64 paths in theory, but as long as you can test that the
} first method always passes the correct class of object to the second,
} and so on, that should be enough for the real world.
And it often is. Good tests help a lot, and I’m not trying to claim they
are useless. I am trying to explain that exhaustive testing is
impossible
for any nontrivial system. I am also trying to make it clear that only
exhaustive testing is the only way to be certain that a system behaves
correctly in all situations, and that TDD does not change that.
There are no silver bullets. TDD is a good approach, and there are many
other complementary development and testing strategies, including static
analysis, that make it easier to develop correct software. None of them
will catch every bug, and none of them can force a mediocre coder to
produce great code. We all do the best we can at our craft, using the
tools
as best we can and, ideally, for the purposes for which they are best
suited.
If this still doesn’t make sense to you, read this 1986 paper by Fred
Brooks:
http://www-inst.eecs.berkeley.edu/~maratb/readings/NoSilverBullet.html
Yes, it’s two decades old. No, nothing has changed in the basic premises
on
which it was written.
} Kerry
–Greg