TDD is BS?
Chris Cain
clcain at uncg.edu
Wed Jun 19 18:15:54 PDT 2013
On Wednesday, 19 June 2013 at 23:44:29 UTC, Walter Bright wrote:
> I just can't accept that. For one thing, implementation details
> often must drive the interface. Just writing specs without any
> knowledge of how it would be implemented will not produce an
> efficient design.
>
> For the square root, there's a definite tradeoff between
> accuracy and speed. With no knowledge of those tradeoffs, and
> just coming up with a spec, how can you make the right
> decisions?
I don't think he's suggesting that it's not important how it's
implemented. He's saying that as far as TDD goes, it's not
concerned with those details. TDD is not going to solve all
specification issues. Personally, I agree with you that square
root functions and similar "low-level" APIs probably have a
different set of needs to satisfy. Realistically, I don't think
anyone would actually TDD something like a square root function.
Personally, I'm a big fan of TDD in general, but I think it's one
of the most often misunderstood things in the field of
programming. It's like if you ask a group of religious people to
define what their deity wants from them... everyone's going to
have a different response and everyone is going to claim that
theirs is the "only one true way."
So, here's my "only one true way" of TDD (tongue in cheek):
TDD (Test Driven Development) has a terrible name. Too many
people think it's about the tests. Tests are certainly a good
side effect of TDD and I certainly can't suggest they don't have
value, but the fact that tests are written is really irrelevant
to what you are _really_ trying to get out of TDD. There's been
numerous attempts to rebrand it (Test Driven Design, Behavior
Driven Development, and Behavior Driven Design to name a few).
Ultimately, the "goal" of TDD is to have the programmer sit down
and look at code from a USER'S (as in, user of the API) point of
view _FIRST_. "Writing a test" as the first step is really just
suggesting "as a user, how would you find it convenient to use
this thing?" That's really just about all there is to it. It's
one of those things that helps guide your thought process. If
you're already doing that without writing tests first, then
great. I've always found it pretty helpful to play around with
how I want code to look like before I actually code the
implementation details, though. More often I can come up with a
simpler and more robust design after playing with how I want the
end result to look like. As a cool bonus, once everything is
done, you'll have a "specification" showing all of the features
of a class/package/module and how everything is used. It will
also show what kinds of preconditions are necessary for using
those things (for instance, does your class need particular
services to be online for it to work? If so, it'll show up in the
tests).
The reason why a square root function seems pointless to TDD to
me is because the whole reason you'd TDD it in the first place is
to figure out how a user should use it. And as far as I'm
concerned, if you have any ideas other than "sqrt(some floating
point number) -> returns a floating point number of the same
precision as the argument which if multiplied by itself is
(nearly) the same as the original argument" you're likely to get
a few strange looks. That problem is solved. The only questions
that might remain is "which package should this be located in?"
which isn't really a question that TDD is meant to solve.
TDD gets more useful once you start designing a larger system
(especially if you're not experienced with designing a bigger
system). If you're a fan of SOLID or some of the other principles
of design, you'll likely see that code developed in TDD will
naturally give rise to some "good practices". For instance, a
major one is IOC/DI. It's much harder to write "testable" code
that doesn't use DI or some technique similar. If you're using
static classes/singletons you'll almost certainly have a lot of
trouble. More often than not, I see people claiming something
isn't testable when they're using things like singletons or
shared resources that really don't need to be shared in the end,
but using TDD would have highlighted that issue in the first
place. That said, if you're experienced you would have probably
not made that mistake, so maybe it's not that important for
everyone.
Anyway, TDD isn't BS, but I do think its misused. The misusage of
it is (sometimes) BS, for sure.
More information about the Digitalmars-d
mailing list