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.

Reply via email to