Why I Hate Test Driven Development
robg3d.com
robg3d.com
It's a lot easier - and a lot more fun - to deal with specific instances, that are concrete, and can be examined and experimented with on a computer.
Logically, one could also work with proofs with a computer to give the same benefits (e.g. coq proof assistant), but for some reason, it doesn't seem to be as much fun in practice. Perhaps because the abstract versions don't have a direct impact; they aren't "live" (idk).
However, the third year I studied how to formally define programming languages and really enjoyed it. It was all about delivery.
I think class size has an effect too - it's much easier to engage with smaller classes. The second year module was mandatory, whereas the third year module was optional.
This is one of my favorites remarks from Dijkstra, but I found it in a video interview with him. I had no idea there's more context to this. Thanks!
But of course, having a mess is bad and goto makes it really easy
Deleted comment
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? assert(sorted(permute((1, 2))) == [(1, 2), (2, 1)])Use assertItemsEqual.
http://docs.python.org/library/unittest.html#unittest.TestCa...
The way I do it:
In the doctest, I include a few toy examples, stuff I can verify by hand, and which helps the user understand what I'm doing.
In the unit tests, I try to do things in the style of Haskell's Quickcheck (the greatest testing library out there). Generate some random values and test properties (e.g., len(permute(x)) == factorial(len(x))).
However, you might find the itertools library helpful, particularly itertools.permutations(): http://docs.python.org/library/itertools.html#itertools.perm...
Otherwise you have to do what I had to last month, which was go back—after the fact—and write unit tests for a large chunk of our code base because we didn't have an automated way of verifying that our logic worked with different (read: non-happy path) data sets.
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.
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.
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.YMMV, while people disagree with the use of mocking, I find it to be valuable to write unit-tests. Does it represent the real-life production grade environment? no, so does the UAT/TEST environment.
It is meant to be that way, nobody able to test in real-life production grade environment (real data, real performance measure). Tests are always done in a more controlled situation.
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.
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.
That said, other times it can be really annoying, too.
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.
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!).
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.
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.
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.
Honestly, I want to sound rude, so I'm going to.
Who the hell are you to tell me what I love or don't love?
Guess what? We're all different.
Watch this sweeping generalization:
If you don't love debugging, I don't think you're a seasoned or valuable programmer.
I call bullexcrement.
I've been coding since before a good portion of the people on this board were sparkles in their parents' eyes. Debugging is a huge time-waster and value-sucker.
Now, if you would say "If you're not good at debugging...", I'd agree with that. But saying one isn't a seasoned or valuable programmer if they don't love debugging just shows a level of immaturity.
Test-driven development will never replace debugging, and saying otherwise implies a misunderstanding of one of them.
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.
I don't like coding. I like telling programmers what to do, thus I'm the boss 0:-)
Ooh, and I also like to spout out long-winded war stories. Who's your daddy?
I, personally, stopped to use debugger more than 10 years ago.