TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

The Pragmatics of TDD

73 pointsby MattRogishabout 12 years ago

17 comments

NateDadabout 12 years ago
I think the only reason TDD works as well as it does is because it forces you to _actually_ write the tests. If you write the tests after the code, it would be perfectly fine.... except no one ever (hyperbole) writes tests after the code, because management/sales/support sees that the code works in the general case, and now insists you work on the next feature and/or you get excited about another feature and don't want to write boring tests.<p>If you write the test first, that can't happen, because you haven't written the actual code yet.
评论 #5332540 未加载
评论 #5332210 未加载
评论 #5332368 未加载
评论 #5332633 未加载
AlwaysBCodingabout 12 years ago
What has always bothered me, is that the ratio of people consistently talking/blogging/tweeting about how important TDD is to the number of actual resources that can help a junior developer learn and practice good testing habits is a million to one.<p>I truly believe that TDD works. I truly believe that the jury is already in and that anyone who is serious about becoming a software professional should write tests for every line of code. I really really believe it and want to use it.<p>That being said, it is so fucking hard to get started with TDD. Oh god, it's so difficult. I've done the katas, done an apprenticeship, read the RSpec book, watched every screencast I could find, everything you can reasonably ask a learning developer to do, and I still find it incredibly impractical to practice TDD when working on most projects, not because I don't want to, but because it's so difficult and time consuming and the resources just aren't there to help make my process quicker.<p>Here's an idea for the TDD crowd. Every time you're about to write a blog post about why people should use TDD, instead write a blog post about a situation where you applied TDD, the tests you wrote and the code it lead to. We need more examples of TDD in progress, more code snippets, more screencasts. I'm telling you the problem is that the resources just aren't there to encourage these habits. Instead of continuing to have this debate at a semantic level, if there were more testing resources available I think people would naturally flock to it and TDD would win out. Until then, I think it's twitter fights and bad habits for the foreseeable future.<p>*This comment applies verbatim to security best practices as well.
评论 #5334300 未加载
评论 #5333408 未加载
评论 #5333352 未加载
DanielBMarkhamabout 12 years ago
I interviewed Uncle Bob on Monday (shameless plug: <a href="http://tiny-giant-books.com/blog/robert-uncle-bob-martin-interview-audio/?id-7" rel="nofollow">http://tiny-giant-books.com/blog/robert-uncle-bob-martin-int...</a>). It was mostly biographical stuff, but I did cover functional programming. There was a bunch of technical stuff I left off because of time constraints.<p>The topic I really wanted to cover but didn't was TDD in startups. I have a simple belief: the value of your code debt can never exceed the value of your code. That is, if you code has no monetary value, it is impossible for you to have any code debt, no matter who you are, what your code does, or what the code looks like. Think about it. It makes sense.<p>It's interesting that Bob took a "saw the baby in half" approach here, outlining the various things he'd throw away and the various things he'd keep. While I think there are definitely shades of gray, it would also be useful for him to directly address the question of code that has no value. If I write a function that I save on my hard drive and never use, does it need a test? I belief the ludicrously obvious answer is "no", but I haven't heard him say that yet.
评论 #5334453 未加载
swansonabout 12 years ago
Write a blog post about a concept or idea in the general sense =&#62; "I need specific examples or this is just a religion/consultant-speak".<p>Write a blog post about specific examples =&#62; "It might work for this example, but in my experience it didn't work in this other case."<p>If you write in the abstract, people will dismiss it as fluff. If you write concretely, people will dismiss it because it doesn't cover their exact case.<p>There is no way to please everyone in the world of opinionated software blogging, so stop trying.
评论 #5332830 未加载
dansoabout 12 years ago
I've only recently started to use TDD, the biggest roadblock being the annoying steps it takes to set up the suite, directory structure (ok, that's pretty minor), and then properly use mocks and stubs. I sometimes forego the latter part.<p>I'm new to it but I find it an incredibly useful strategy. It forces orthogonality on me because I have to think how a function can be tested independently of the external objects that may use it...which causes me to challenge my initial assumptions and instincts about the overall application design.<p>In some sense, I guess, it is always frustrating to spend more time in the design stage than working with an actual prototype...but I find the medium-to-long term benefits to far outweigh the initial investment in time. And once the tests have been written, the actual functional code is almost trivial to write.<p>Even without the benefits TDD has in easing the maintenance/upgrade phase of a product, I find its effects on the design/prototype stage to be worth the effort alone.
评论 #5332654 未加载
jfabreabout 12 years ago
I've seen big company devs so overwhelmed by messy production code that any small feature change would require 2 weeks of work.<p>I've seen startup devs who couldn't cope with changing requirements fast enough. There was just too many moving parts at the same time.<p>Hell, I've been one of those devs! Great code is the exception, not the norm.<p>When I learned TDD, it greatly improved the quality of my code. If TDD is a bottleneck for you, maybe you need to learn to touch type.<p>My 2 cents.
评论 #5331954 未加载
评论 #5333516 未加载
评论 #5332152 未加载
plinkplonkabout 12 years ago
I'm surprised at how much attention this bit of process dogma is getting on HN.<p>This particular argument about the supposed efficacy of TDD depends on people accepting the equivalence of the efficiacy of TDD with the efficiacy of surgeons washing hands, just because the blog author says so.<p>Oh horror, how can you challenge my dogma just because I call it a 'discipline' and <i>verbally</i> equate it to surgeons washing hands.<p>Saying something is true doesn't prove it is true whether you call something a 'discipline' or not. Cults are full of such 'disciplines'. Cult members will vouch for them. A better word is 'ritual'. At best such rituals are cargo cult practices. [1]<p>Surgeons washing hands is a practice with empirical, unchallengeable <i>scientific</i> evidence supporting it,while TDD is a dogmatic practice evangelized by software process zealots, with next to no scientific evidence backing it up.<p>Also TDD != testing and TDD != automated testing (though the evangelizers tend to blur the differences. It is easier to argue that you should write tests, than that you should write tests <i>before</i> you write the code, which is a somewhat more shaky assertion. If you can paint your opponents as opposing <i>tests</i> (vs TDD) you have set up an easily knocked down strawman).<p>Programmers have written tests, including automated regression tests for <i>decades</i> without the blind adherence to the 'write a test <i>first</i>, write the code, refactor, repeat' cycle that TDD consists of.<p>Insisting on this as some kind of <i>moral</i> imperative [2] is snake oil, and it is natural that experienced devs push back against religious preaching.<p>The best 'poke holes in the zealotry gently but firmly' writing wrt TDD is at <a href="http://www.dalkescientific.com/writings/diary/archive/2009/12/29/problems_with_tdd.html" rel="nofollow">http://www.dalkescientific.com/writings/diary/archive/2009/1...</a> . Bob Martin's TDD 'kata' is dealt with there in some detail. The comment thread at <a href="http://dalkescientific.blogspot.in/2009/12/problems-with-tdd.html" rel="nofollow">http://dalkescientific.blogspot.in/2009/12/problems-with-tdd...</a> is hilarious too, with some familiar names popping up.<p>[1] <a href="http://en.wikipedia.org/wiki/Cargo_cult" rel="nofollow">http://en.wikipedia.org/wiki/Cargo_cult</a><p>[2] The author says as much here <a href="http://news.ycombinator.com/item?id=5331108" rel="nofollow">http://news.ycombinator.com/item?id=5331108</a><p>" [TDD] allowed us to go fast, and _keep_ going fast because the code stayed clean. I have come to view it as a moral imperative. No project team should ever lose control of their code; and any slowdown represents that loss of control."
评论 #5332171 未加载
评论 #5332269 未加载
评论 #5335505 未加载
评论 #5333371 未加载
tieTYTabout 12 years ago
"I don't write tests for one line functions or functions that are obviously trivial. Again, they'll be tested indirectly."<p>The funny thing about this is when I read this bullet point I thought, "Bob Martin would disagree with this". His rules for TDD ( <a href="http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd" rel="nofollow">http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd</a> ) would force that method to be tested whether he wants to or not. Then I scroll down to see who wrote the article... Bob Martin<p>EDIT: But maybe he meant to emphasize "indirectly". Maybe it was under test at first but then got extracted into a simple method under refactoring.
评论 #5335606 未加载
评论 #5335140 未加载
eaurougeabout 12 years ago
For me the greatest benefit of TDD is that I can first specify how a unit of code is expected (by me the implementer) to behave. Then I write the code that fulfills (just) those specs, without writing any unnecessary lines of code. If you've read the specs then you know how the code behaves. Yes, you can write the code first then the tests, and I do and have done that. But there's something to be said for letting the specifications alone determine what makes it into code. Of course, you need to know the specifications for this to work, which isn't always the case.
cshipleyabout 12 years ago
It looks to me like another blog posting by a TDD evangelist, most of which I ignore because he ain't preaching my religion. He did, however, touch on what the important part of the pragmatic vs dogmatic question. This jumped out at me:<p>&#62; In general I don't write tests for any code that I have to "fiddle" into place by trial and error.<p>It is congruent with a some general rules I follow to decide if I should write a test for something:<p>1) Do I care if this code doesn't work on the non happy-path? Maybe I'm writing some isolated prototype code that will probably be thrown away, or perhaps I'm planning to rewrite it later. I'm not going to bother writing tests.<p>2) How important is it that this code is bug free, and how soon should there's a bug. If, say, the code is in a highly used part of the program that is required by the rest of the app to function properly. Or it is part of the main feature set. I definitely will write tests.<p>3) I'm under time constraints. If I don't have the time to write tests for a particular part of the code, then I don't have time.<p>4) How solid is the architecture/interfaces? If I expect them to change quite a bit, then I will not write so many tests, or perhaps any. I once worked on a project that was heavy into unit testing/tdd. There was hundreds of tests written very early on in the project, and since the code was changing so much, we spent a lot of time re-writing tests. It eventually got to be a huge time sink.<p>5) How much money does the project have? Writing lots of tests takes time, and time is money. I've worked on some projects that have budge (or time) constraints, so I don't have the luxury of such dogma.<p>All that said, I often dislike programming religions or dogma, because they often advocate following a practice somewhat blindly, without understanding when the rules/precepts should be applied.
jbrainsabout 12 years ago
TDD is a fundamental learning technique. It teaches the principles of modular design. Notice! One can learn modular design in a variety of ways. I make no claim that TDD is "the only" nor "the best" of these, but I claim that it works for enough people to merit attention.<p>Learning requires investment. Investment carries risk. Risk aversion/tolerance is a very personal and contextual thing. There's almost no point arguing about when it's good to be risk averse and when it's good to be risk tolerant, because of this heavy coupling to the context. Better to be aware of the phenomenon and work things out case by case.<p>Some people generally don't like to learn. Nothing you do will force them to like to learn. You can invite them to try to learn; you can try to make it comfortable and safe for them. That might work.<p>Some people find such value in a learning technique that they continue to use it, even after learning 99% of what they will ever learn from it. Continuing to use the technique provides them comfort. Whatever works. Others eventually break free of the learning technique, knowing that they can fall back on it when they feel pressure.<p>I care about this: people who want to practise TDD should be free to do it; people who don't want to practise TDD should not be forced to do it. Everything else is noise.
jbaudanzaabout 12 years ago
<i>I usually don't write tests for frameworks, databases, web-servers, or other third-party software that is supposed to work. I mock these things out, and test my code, not theirs.</i><p>If your software has a dependency on a third party component, then you should include that component in your tests. It's not about testing the component, it's about testing your integration with that component. For example, if you upgrade that component, and the API changes in a way that breaks your integration, you want your test suite to break as well.<p>Sometimes if a component is too slow or requires network access, you have to mock it out. But as a general rule, it's best to leave your dependencies in place.
评论 #5332867 未加载
ternaryoperatorabout 12 years ago
My greatest reservation about TDD is one that's almost never referred to by its practitioners: the need for strong refactoring skills. To do TDD right, you've got to be really good at refactoring your code. But many developers know only basic refactoring techniques. So if they do TDD, they end up generating code that looks like it was written to satisfy lots of small requirements, and it lacks the cohesion and clarity that it should have.<p>I think TDD is taught the wrong way around. First, they should teach refactoring. And only when those skills are thoroughly mastered, should they move on to teaching TDD.
njharmanabout 12 years ago
&#62;I don't write tests for getters and setters. &#62;I don't write tests for member variables. &#62;I don't write tests for one line functions or functions that are obviously trivial.<p>I don't disagree, but I often have at least one test that explicitly exercises all of the public interface (of a class/module/whatever). The point is when I change that interface I want tests to break and not have to rely on my memory on what changed when writing release notes / incrementing version number. I mostly test python, YMMV.
评论 #5334327 未加载
unclebobmartinabout 12 years ago
What I find fascinating in all this is the sheer amplitude of the invectives. Apparently TDD pushes some people's buttons. I think that's a good thing.
codeulikeabout 12 years ago
The measure is: Find a startup that uses TDD religously, find one that just uses it when it suits them, find one that doesn't use TDD at all. Fix all other variables. See which startup does the best. This is a hard experiment to do but if anyone want to offer me a grant for the research, get in touch. Thanks.
评论 #5332891 未加载
评论 #5332963 未加载
jdlshoreabout 12 years ago
The cost/value tradeoff of TDD keeps coming up. My comments on this last time were well-received. The question was "Should I TDD an MVP?" but the answer is really appropriate to any question of when and whether TDD is worth it:<p>This is a really good and interesting question, and it's one I've been struggling with myself.<p>The problem boils down to this: TDD makes your software more maintainable (if you do it well) and it lowers your cost of development. However, it also takes significant time and effort to figure out how to test-drive a technology for the first time. Everybody can TDD a Stack class; TDD'ing a database, or a web server, or JavaScript [0] is a lot harder.<p>So the answer seems simple: use TDD for the parts you already know how to TDD.<p>But it's not so simple! It's much harder to add tests to existing code than it is to TDD it from scratch. Sometimes, it's flat-out impossible. The expense is so high, there's a very good chance that you'll never get around to adding tests to the un-TDD'd code. It will hang around causing bugs, preventing refactoring, and sapping your agility forever, or until you rewrite... and a rewrite of any significance will halt your company in its tracks, so you won't do that.<p>So the reality is that, anything you don't TDD from the beginning, you'll probably never be able to TDD. Companies that go down this road find themselves doing a major rewrite several years down the road, and that's crippling [1].<p>There's another wrinkle on top of this: manually testing code and fixing bugs is <i>expensive</i>. Once your codebase gets above a certain size--about six developer-weeks of effort, let's say--the cost to manually test everything exceeds the cost to TDD it. (The six weeks number is a guess. Some people argue it's less than that.)<p>So the real answer is a bit more nuanced:<p>1. If your MVP is truly a throw-away product that will take less than six weeks to build and deploy and you'll never build on it after that, use TDD only where it makes you immediately faster.<p>2. If your MVP is the basis of a long-lived product, use TDD for the parts you know how to TDD and <i>don't do</i> the parts you don't know how to TDD. Be creative about cutting scope. If you must do something you don't know how to TDD, figure it out and TDD it.<p>3. It's okay to be a bit sloppy about TDD'ing the edges of your app that are easily rewritten or isolated in modules. But be very careful about the core of your system.<p>That's my opinion based on 13 years of doing this stuff, including building five successively-less-minimal MVPs over the last nine months for my JS screencast. The first three MVPs were zero coding, the fourth was a throw-away site, and the fifth was TDD'd with aggressive scope cutting to minimize the number of technologies that had to be TDD'd.<p>[0] Shameless plug: I have a screencast on TDD'ing JavaScript. <a href="http://www.letscodejavascript.com" rel="nofollow">http://www.letscodejavascript.com</a><p>[1] Rewrites are crippling: See Joel Spolsky's "Things You Should Never Do, Part I." <a href="http://www.joelonsoftware.com/articles/fog0000000069.html" rel="nofollow">http://www.joelonsoftware.com/articles/fog0000000069.html</a> (There is no Part II, by the way.)