
Why I Hate Test Driven Development - reinhardt
http://www.robg3d.com/?p=949
======
begriffs
Reminds me of what Edsger Dijkstra wrote, "Let me start with a well-
established fact: by and large the programming community displays a very
ambivalent attitude towards the problem of program correctness. A major part
of the average programmer's activity is devoted to debugging, and from this
observation we may conclude that the correctness of his programs —or should we
say: their patent incorrectness?— is for him a matter of considerable concern.
I claim that a programmer has only done a decent job when his program is
flawless and not when his program is functioning properly only most of the
time. But I have had plenty of opportunity to observe that this suggestion is
repulsive to many professional programmers: they object to it violently!
Apparently, many programmers derive the major part of their intellectual
satisfaction and professional excitement from not quite understanding what
they are doing. In this streamlined age, one of our most under-nourished
psychological needs is the craving for Black Magic, and apparently the
automatic computer can satisfy this need for the professional software
engineers, who are secretly enthralled by the gigantic risks they take in
their daring irresponsibility. They revel in the puzzles posed by the task of
debugging. They defend —by appealing to all sorts of supposed Laws of Nature—
the right of existence of their program bugs, because they are so attached to
them: without the bugs, they feel, programming would no longer be what is used
to be! (In the latter feeling I think —if I may say so— that they are quite
correct.)" -- From EWD288

~~~
jsprinkles
Next, tell us why goto is bad.

~~~
raverbashing
It's not necessarily bad, for example, see how it's used on the linux kernel
(+/- like an exception handler)

But of course, having a mess is bad and goto makes it really easy

------
Fice
I tend not to like TDD for a different and serious reasons. TDD seems to
encourage bad trial and error programming practices where developer blindly
modifies the code until it passes the tests instead of reasoning about
correctness based on algorithms and specifications. TDD does not consider that
even a program that work correctly in the current environment for any possible
set of input data is still incorrect if it violates contracts defined in APIs
and protocols. Remember how the correct update to the memcpy implementation in
glibc broke programs that incorrectly used it for overlapping memory regions.

~~~
drostie
My problem is more that I never know what to test. I mean, suppose I have some
nontrivial code -- one of my latest random projects contains this:

    
    
        def permute(tpl):
            """Gives the set of valid permutations for this tuple."""
            if len(tpl) == 0:
                yield ()
            else:
                for t in permute(tpl[1:]):
                    for n in range(0, len(t) + 1):
                        yield t[0:n] + (tpl[0],) + t[n:]
    

It's a recursive generator-driven permutation engine. Technically I suppose
the order of the permutations doesn't matter, so long as they are all distinct
and there are n! of them. Is that what I should be testing? That is, should my
test code read:

    
    
        permute_test = tuple(permute((1, 2, 3, 4)))
        assert(len(permute_test) == 24)
        for i in range(0, 24):
            assert(len(permute_test[i]) == 4)
    
        for i in range(0, 23):
            for j in range(i + 1, 24):
                assert(permute_test[i] != permute_test[j])
    

...? And if so, how does that help me write the original function? Or am I
supposed to test a base case and one or two recursion steps, so that it helps
me write the function, but "hard-wires" a particular order?

~~~
mcobrien
You're right to want to avoid duplicating your code inside your test. In this
case, I'd work out some simple permutations and test against those values,
sorting the results so order doesn't matter.

    
    
        assert(sorted(permute((1, 2))) == [(1, 2), (2, 1)])

------
kiba
I hate TDD because I have to actually debug them, sometime more so than the
actual app themselves. Also, there's the issue of slow TDD suite, which means
you have to optimize them or otherwise it will slow down your development
pace.

TDD is only good when it provide more benefits than its negative(debugging
time, time waiting for it to run, time spent ripping out code).

That being said, it's better than 0 test. Just don't get crazy in writing
testcase for every minute scenarios.

~~~
boyter
Unless of course you are writing software that goes into a pacemaker, in which
case I would want that tested like crazy for every possible scenario you can
imagine including automated fuzz testing. Same goes for databases and quite a
few other classes of software.

In short, use common sense.

Personally I love TDD. Not because of the tests, but because the resulting
code IS testable, and generally testable code is maintainable and easy to
read.

~~~
Retric
If I knew one pacemaker was developed with TDD and one without it I would
probably go for the one without it. Most programs are fine on the Happy Path,
and TDD seems like it's focused on expanding the Happy Path vs actually
writing correct software.

This could just be internal bias, but without TDD programmers more focused on
the possible error conditions. I would rather see:

    
    
      If ((a/2-1) + (b/2-1)) > (largestInt/2-5)) 
      ... do something
      vs.
      A large try catch block.
    

Arguably the second is just as safe, but it's the test's you don't think to
run that tend to end up as production bugs and good tests require a level of
paranoia which is more important than methodology IMO.

------
kfcm
You have got to be kidding.

Debugging code (especially others') is one of the most heinous activities on
this planet. I have lost years of my life fixing what others have created
broken (intentionally and otherwise). Years and special occasions that I can
never get back because some moron's mission-critical code decided to break,
with the ultimatum that no one could leave for $(Holiday of Choice) until
fixed.

It's because of having to debug that I left development and went into a
different area of technology. TDD is the only reason I even consider doing ANY
development now.

People who enjoy debugging are the ones I hope work themselves into
obsolescence.

~~~
nocman
Personal time lost to fixing problems can always be annoying. However, not all
debugging situations are like that.

There is something terribly satisfying about digging into a problem on a
production system that rears its ugly head once a month (requiring a system to
be rebooted), brainstorming, setting up test scenarios, getting the bug
reproduced, finding the source of the problem, fixing it, testing it and
seeing that it has been nailed! (oh, and equally satisfying is seeing the days
of uptime on said machine thereafter measured in 3 digit numbers :-D)

And the problem I have in mind _was_ someone elses code. I still enjoyed every
minute of the debugging process.

------
wpietri
I feel this myself.

However, I have always had the most fun debugging other people's systems.
Because under those conditions I'm always billing by the hour, and when I find
the problem it's never my mistake.

For my own code, though, I prefer TDD. And these days I still get enough
debugging exercise when dealing with third-party systems. Facebook API, I'm
looking at you here.

------
philwelch
Oh look, the "bait and switch" style of linkbait.

------
shtylman
I can't be the only one who thinks this is meant to be sarcasm?

~~~
wavephorm
Yeah, it's very subtle. He's essentially saying that the TDD approach has made
his code is flawless, and he is incapable of producing bugs.

~~~
chj
Ahh.. I must lack some sense of humor.

~~~
justinjlynn
Don't worry, you're not alone. I, for one, congenitally lack a sense of humor
myself.

------
rmoriz
Some people should debug their irony detector code as this is clearly irony.
Great irony :)

------
gouranga
Great article. Between TDD, dotting constraint checks all around my code and
actually knowing what I want before I write it, I rarely have to use any
debugger.

With respect to people feeling like TDD is a waste of time, this thought is
immediately extinguished the moment you see an accidental regression get
flagged instantly, resulting in you NOT having to spend hours finding it.

Debugging is one of those tasks that you don't really want to have to do
either. If you're debugging all the time, you are doing things wrong. I don't
find debugging fun - I find problem solving fun (not problems I've created!).

------
chj
It is easy, don't TDD every project.

Wasted some time on TDD before, slow, like robot, generate tons of code that
never be shipped. Nowadays, I just read through the code like it was written
by another idiot, understand it, and you know what, I am actually refactor it
more often, and keep improving it even though it doesn't fix a known bug. You
have better understanding of your code, and then when something goes wrong, it
is pretty easy for you to figure out what could be the cause. However, this
approach doesn't fit for thrown-away type of projects.

------
geoffpado
If he's really looking from the satisfaction from debugging as more of a self-
morale booster, why not contribute bug fixes to an open-source project? Find a
major project, open its issue tracker, and start bug hunting!

I'm sure the maintainers of whatever project he picks will love having someone
around to fix bugs, and he both gets the enjoyment he "misses", and gets to
hone some debugging skills.

------
jakejake
I can _kinda_ relate to having fun fixing bugs, but I think (i addition to
some sarcasm) the author is kinda romanticizing debugging. 90% of the time
it's no fun, feels like a waste of time and doesn't really provide much
satisfaction. Once in a while, though, you do find a really interesting bug
and fix it and it feels pretty great!

~~~
LaRakel
Creating tests usually feels like a waste of time as well.

~~~
vlisivka
Execute all these test cases by hands 10 times a day and feel the difference.
You will enjoy automating after that.

------
EugeneOZ
"I have no problem saying that I write good code" - funny, read about
<http://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect>

------
jmonegro
I can relate to this sentiment. I've always described software development as
moments of great frustration followed by great satisfaction. I just love the
feeling that comes after you've squashed a nasty bug.

------
kaiwen1
These programs I write, I curse them. So clean and faultless, so hideously
optimized. My bugs, my passion, so close at hand, yet out of reach, squandered
in the face of my boundless talent.

------
usablebytes
Sweet surprise. I jumped in to see the problems and rather found a positive
side. @binspace rightly says, "Humor in programming considered hardful" :)

------
johnl87
Debugging is not fun when your program is leaking memory and you're not sure
why, and existing code tools don't tell you why. Especially if you're writing
drivers. Sure, stepping through python code might be fun, but not low level
c/c++ code where you're in a call stack that's 20 levels deep and half the
time you don't have source for the parts the code breaks or asserts on.

~~~
alexchamberlain
What about the level of excitement you get when you find a bug in an
underlying Fortran library linked in by code building tools because of a
random header file someone included without thinking too much?

------
udkl
Spend your new found time on creating new projects to solve real world
problems !

------
pthread
_This is a good thing, isn’t it? So why do I hate TDD?

Because debugging is fun. There, I said it. I love debugging. I think lots of
clever people like debugging._

I've been doing embedded development for quite some time, so you know,
flipping bits like a boss, a shitload of open terminals, lots of cables
everywhere all the stuff that makes you look like you know what you're doing
but debugging is not fun, it never was, it's a huge waste of my time.

You know what's fun? Having a product that works.

Debugging is code monkey job, you don't do it because you're smart, you're
doing it because you were foolish.

To love debugging is to not love to code.

~~~
jsprinkles
I debug because I'm smart, and I enjoy it, and I frequently find bugs that I
didn't know existed by seeing inside a frame as it's executing. Debugging is a
crucial skill in many fields, _particularly_ embedded work (which is the irony
in your comment), and the insight from breakpoints and a couple afternoons of
digging is unique among our tools. I hate sweeping generalizations of how
programming should be done, regardless of what they are.

Watch this sweeping generalization:

If you don't love debugging, I don't think you're a seasoned or valuable
programmer.

~~~
pthread
If you love debugging, I don't think you're a seasoned or valuable programmer.

~~~
jrockway
That's quite a generalization. Debugging does not necessarily mean debugging
your own code: you might have stumbled upon a compiler bug, or a timing bug
with your hardware, or you may be trying to buffer overflow some massive
proprietary database so you can take over the world. All of those tasks will
involve lots of time looking at memory addresses and hex dumps, but none of
them mean the person doing it is a bad programmer.

~~~
vlisivka
Why you need to look at them manually? Computer will compare all that much
faster.

If you are good programmer and bug is non-trivial, you will create code to
catch bug much faster than you will catch it manually. Moreover, you will be
rewarded next time, because your code will be already written and ready to
use.

~~~
jrockway
Let's call it "exploratory programming" instead of debugging. Yes, your
computer will run unit tests. No, your computer will not notice that memory is
being corrupted because of a particular sequence of instructions emitted by
the compiler. To solve a problem, you have to understand it. And if you're
writing code to solve a problem that's well-understood, you should have just
downloaded the library instead.

~~~
vlisivka
Did you ever saw how program crashes when run, but works fine in debugger (or
vice versa)? What you will do in such case? What you will do _after_ few such
cases?

