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