5 ms·
As for Joel’s consistent dismissal of unit testing, he’s just wrong about that. Unit testing (done TDD style) does not slow you down, it speeds you up. This se
by andreyf 17y ago
As for Joel’s consistent dismissal of unit testing, he’s just wrong about that. Unit testing (done TDD style) does not slow you down, it speeds you up.
This seems logically impossible. Maybe I'm misunderstanding TDD, but at the heart of it, TDD seems to suggest you:
1) Give instructions that describe how to check the instructions you're about to give are correct
2) Give instructions
This is not the right solution to the problem "I'm unable to give the computer the instructions I intend". At the very fundamental level, it clashes with DRY, and is only effective if you're very uncertain in your ability to do (2). The right solution is improving your ability to do (2) - by creating better abstractions and metaphors, not by repeating yourself.
- pseale 17y agoOne of the things I like about the TDD experience is it assumes you're not a 'strong enough programmer' and works with your failings. If you're the perfect OO programmer who has memorized all APIs, TDD is worthless, because you can just bang out code the first time correctly. If you write perfect code, why bother exercising your code first in tests when you write it correctly the first time, every time? For me, it helps. I'm going to go out on a limb and say it will help you too. If you haven't tried TDD, I'd recommend attempting it at least once, maybe try running through a simple problem with a partner or at a coding dojo.
- plinkplonk 17y ago"As for Joel’s consistent dismissal of unit testing, he’s just wrong about that. Unit testing (done TDD style) does not slow you down, it speeds you up." One assertion counters another. Joel is wrong because "Uncle" Bob says so. Why do TDD zealots sound like religious preachers? No harm writing unit tests. They serve well for (a certain amount of) regression testing. The whole Test Driven approach to designing software is more dubious (but wildly endorsed by the Agile consultant crowd). More sober developers seem to disagree. From Coders at Work "Seibel: What about the idea of using tests to drive design? Norvig: I see tests more as a way of correcting errors rather than as a way of design. This extreme approach of saying, “Well, the first thing you do is write a test that says I get the right answer at the end,” and then you run it and see that it fails, and then you say, “What do I need next?”—that doesn’t seem like the right way to design something to me."
- hs 17y agothese great doers who shape the world don't seem to like unit testing. i'll follow them, at least because they are smarter than those bloggers.
- gjm11 17y agoIf you happen not to be as smart as the Great Doers, then imitating them might turn out to be a bad idea.
- raganwald 17y agodo not follow in the footsteps of the sages, seek what they sought.
- plinkplonk 17y ago"do not follow in the footsteps of the sages, seek what they sought." but do listen to their advice and do your own thinking. The point is not to write tests because Norvig doesn't, or equally, to write tests because "Uncle" Bob does. Just think about what they say before copying them blindly especially when you encounter methodology vendors, "naked men who sell you their shirt" as it were, and not succumb to the latest snake oil nostrum just because its vendors have loud voices.
- kscaldef 17y agoAh, yes, the "I don't have to write tests because I'm perfect" school of programming. 1) You aren't perfect. 2) Your coworkers aren't perfect. 3) Your "abstractions" are still code that can have errors in it Also, you are misunderstanding the argument that TDD speeds you up. Yes, at the micro level it may take a bit more time. But, as the system grows, your ability to add or change functionality without breaking things increases when you have tests to verify that it is still correct. (Also, automated testing is much, much faster than manual testing.)
- wvenable 17y agoBut, as the system grows, your ability to add or change functionality without breaking things I disagree unless all your changes are really shallow. You change the structure of your application in significant ways and you'll break the tests too. So now you have two problems.
- Periodic 17y agoThe code and the tests go together. You don't just make a pile of code, and a pile of tests, and hope they all go together right. You have some big tests that are general and test that all the components work together, but for each component you have lots of little tests, and if you are going to change the component you change the tests FIRST. That's TDD. You deliberately break the tests before you change one line of the actual code.
- wvenable 17y agoSee, I think the value in tests would be that they are reusable. If you're smart enough to write a test for a situation, then you're smart enough to code for that situation in the first place (and conversely if you miss an edge case in code, you're just as likely to miss an edge case in testing). If you're constantly rewriting your tests -- what's the gain? Now certainly writing everything twice is actually a great way to catch errors. NASA does that with the shuttle. But I wouldn't argue that its faster. I prefer to just liberally sprinkle my code with run-time assertions. We have a small defect rate even after pushing out massive structural changes to the application. The bugs that we do have tend to involve an unpredictable set of conditions that no automated test would ever be written to find.
- j_baker 17y agoUnit tests are indeed productivity tools. You'd be surprised at how many stupid little errors you can catch by running tests. In fact, I would argue that unit tests improve code quality more because they give you more time to focus on the big picture without having to worry about stupid things breaking all the time.
- evgen 17y agoAlternative, you could just practice not breaking shit. Two erroneous assumptions in your thesis are that 1) unit tests catch all stupid little errors so you can stop worrying about them, and 2) the time spent chasing down stupid little errors that would have been caught by your tests is made up for by the cost of creating those tests in the first place. Unit tests are not magic fairy dust. Having them does not make your code bug-free and even if something is covered by a test it is still possible that both the test and the code are wrong in the same way. Putting too much belief in correctness due to tests passing can be just as bad as not having any tests at all. Unit tests are great at api boundaries and points of interface between data-munging code, but every function or process does not need its own unit test. Unit tests also have a high up-front cost that is frequently not justified by the return on this investment. There is a subtle art to selecting the granularity of testing that takes a while to learn, and spending too much time around TDD zealots will often lead coders who have not learned this skill to waste time writing tests instead of getting things done. Like IDEs that flag type errors, compiler warnings, and debugger breakpoints, a test is just a tool. If you can't write working, maintainable code without any of these tools then perhaps you should spend more time honing your craft instead of collecting another crutch.
- bkovitz 17y agoTDD is not a tool for preventing errors, although it has that effect. It's primarily a way to use the computer to help you design. It's an attention-helper. Here are two things you have to do when programming: start with a problem that is somewhat vaguely specified and flesh it out, and break problems down into very tiny subproblems. We all have lots of ways of doing those things: talking with another programmer, writing things down in a notebook, writing a little bit of throwaway code to flesh out an idea or convince yourself that it works. TDD gets the computer involved in that process. You can't solve the whole problem this minute, but you can bite off a piece. Saying, "I'll write a little unit test for this" means you're not just thinking, you're really seeing how your approach works. You're getting very clear. Now suppose you find that something is hard to test. This is often a sign that it's coupled to the rest of the system in a bad way. When you have a lot of tests, you can try out new ideas very quickly and see if you've overlooked something, or quickly get an idea of how much code needs to change to accommodate the new idea. A big benefit of TDD is that it leads you to write much simpler code than you otherwise would. I don't expect my say-so to convince you of this; it's just something you have to play with and see for yourself. Many times, I've found that something like an if statement was all I actually needed to accomplish something that looked like it was going to be hard. I found the simple way because I wrote the test first. Sometimes, the resulting code doesn't feel like "I" wrote it. It has a strangely minimalist quality. The biggest benefit of TDD, though, is as a tool for communication within a team. When pairing, the unit tests make very clear what the current problem is. When understanding someone else's code, the unit tests make very clear how you're supposed to call some code. When you modify someone else's complex code, well, that's when you really start to value unit tests. The unit tests store knowledge of the program in a way that humans can understand and the computer can verify. Of course TDD does not solve all problems. It's just a neat tool, which often produces simpler code than you could write "by yourself". You should know what it's for, though. It's a design helper, not a QA department. If it's not helping you design better, then you shouldn't use it.