Earlier quoted context omitted.
You make a trade-off. Do sounds weird, and I have no idea why. :)
I guess because we make compromises and make deals.
Ask HN: Help me see why everyone seems to love TDD?
61–70 of 89 posts
Re: Ask HN: Help me see why everyone seems to love TDD?
#62TBH, I don't know anyone who does TDD. I only know a few handfuls of developers, but so far the only people I've briefly met that do TDD were ones selling it; the consulting company that came into the company I worked for. This consulting company tried to "teach" us TDD at the same time as I think they were learning it. Not a single developer out of the ~40 on our teams bought into it, because in almost all cases the…
I'm not sure I understand your perspective. If you have a specification (shouldn't a web app have a specification? Admittedly, I've never developed one, my world is embedded), then you have something to write your tests too. While we don't use unit tests in my office, we do use comprehensive testing and a (mostly) TDD style (accidentally or coincidentally, our process has operated in roughly the same way for 30 years…
A specification doesn't translate directly into code. Otherwise, developers wouldn't have jobs. A specification is interpreted by developers, then reinterpreted by other developers, managers, etc., then updated, etc.
Re: Ask HN: Help me see why everyone seems to love TDD?
#63The deal with TDD is you write twice as much code and you have less than half the bugs. As the project grows, it gets harder and harder to maintain and change unless you have good tests. Most projects without good tests that I've seen grow to a certain size and then become very difficult to make progress on because people are too scared of breaking things and the releases inevitably take a very long time due to all t…
Also, having "more" things break other things in a big project is more of a modularization/encapsulation kind of issue, that doesn't get better or worse with tests.
At the moment I'm looking into static typing as alternative. I suspect this to be a "tests-in-code" kinda thing, which could eliminate many unit tests. Also with modern type inference and structural typing (I'm trying TypeScript) this could scale better than "write twice as much code".
Re: Ask HN: Help me see why everyone seems to love TDD?
#64Have you actually lived in a TDD world? Actually sat down and did the entire thing? I don't think it is worth it. Tests are good. Fire manual QA team and hire people to write automated integration tests. But actually designing your code around tests? It tends to lead to brittle systems that do a lot of dumb things. Write the code what works best, then add some tests around it where required. 40% coverage could be eno…
> Fire manual QA team and hire people to write automated integration tests. From experience, this leads to coders coding-to-the-tests. It compiles, it passes, ship it. Does it doing the right thing under stress? Who knows. Manual QA staff, proper QA staff, do crazy non-linear things that stresses code like customers do. I'll bet they would have caught that bug in the other front-page story about the animal feeders fa…
You know why this never happens? Performance is never a requirement, almost always an afterthought. How many specs list required throughput or 99.99 percentile latency?
No one cares about perf until it's bad. So if we fix that, put in the spec... We can automate perf testing and perf monitoring. Sure have a perf team code this. But I don't need a QA guy to run a perf test for me.
Re: Ask HN: Help me see why everyone seems to love TDD?
#65That said, there is a fairly large difference in experience and skill required to learn how to write variable names that make you more productive and how to write unit tests that make you more productive.
It all comes down to TCO of the system to users. In many cases, high test coverage does reduce TCO, but this is difficult to see during the first year of the project. And note too that the risk of increasing TCO due to poorly written unit test code is real. You can do more harm than good by creating flaky ad-hoc unit tests that are slow to run, difficult to change, and make refactoring of production code PITA.
The reason we do TDD, is that has some unique benefits. Especially, if you aim to use "full TDD" in the sense that no line production code is written before there is a failing test for that line.
What your life would be like if every time you interrupt a programmer in your team, everything she was working on compiled and passed all its tests less than two minutes ago? And if you'd have an always up-to-date spec that is so precisely written, it executes? And deployment to production would be a business decision instead of technical one as you'd be ready to deploy practically whenever you feel like it? And if you decided to swap MSSQL for PostgreSQL in your production system, you could do it without breaking a sweat?
What would your life be like if you did not have to fear breaking anything when cleaning up code? If you'd be able to keep your system maintainable and you'd know it?
If TDD is so great, why then, it is not used more often? I can only speculate, but I think this comes back to the question of developer skills. I have mentioned some of this before here at HN, but I'll reiterate.
I have noticed that I have to make large refactorings to move things around to arrange the whole system so that each part can be tested without too much effort. To do this I have to view most things in terms of the interfaces they provide. On the test side, I have to write the test code so that the what the test does is strictly separated from how the test does it. This way changing the system causes only minor changes to ripple to the majority of the test code. This is by far the most common paint point of a novice TDD'er.
Based on this, it seems that programming with TDD is a distinct skill-set that requires significant effort to get reasonably good at, i.e., to be more productive than without TDD. I have given it a try on medium-size projects and it does pay off in terms of simplicity of the design (I have to manage dependencies and decouple external systems and components quite heavily), low defect rates in production/QA, way less time spent in debugger, and relatively high velocity (this is notoriously hard to measure cross projects/teams, but at least this was true based on customer and product owner feedback).
However, the problem with TDD is that all of the above (tests decoupled from interface, interface decoupled from implementation, system decoupled from external systems, components decoupled from each other, design skills to recognize this, and refactoring skills to do this fast enough to remain productive) need to be done well enough at the same time. Otherwise the approach falls into pieces at some point.
To paraphrase Uncle Bob from some years ago: "I have only been doing TDD for five years, so I am fairly new to it..." Half of the programmers have that much experience in programming in general, so the amount of time required to hone TDD and refactoring skills may not be there yet.
TDD'ing requires months or years of practice to get really productive with, and has a fairly large set of prerequisites that one has to know in order to remain sane. It took me several years of experimenting (especially with different techniques of writing unit tests) before I found a way to be productive with TDD. I also drew the connection between testability and program architecture (aggressive decoupling) fairly recently (some four years ago), and that was one of the last pieces of the puzzle that made everything work. The system structure is especially crucial for writing fast unit tests. You really want the dependencies to external systems (DB, UI, Network, MQ, OS, Library, Framework, or the like) injected and abstracted behind and an interface.
If your system's design results in your unit tests depend on volatile components, your system becomes unnecessarily complex. This is because volatile components change often and these changes ripple to your units tests effectively rendering them volatile too. Avoiding this problem has been captured, among others, by the Stable Dependencies Principle (http://c2.com/cgi/wiki?StableDependenciesPrinciple), which states that the dependencies should be in the direction of the stability. A related one is the Stable Abstractions Principle (http://c2.com/cgi/wiki?StableAbstractionsPrinciple), which states that components should be as abstract as they are stable.
When I started with TDD, my productivity plummeted initially, but the benefits were too good, and I slowly found the techniques needed to keep up with my old self in terms of produced features. I dread to think the pieces of code that send me deep down into debugging sessions due to non-existent test coverage.
Part of the problem is that there are not that many TDD codebases or TDD'ers around. Also, this is probably not something you can pick up while doing toy projects or school assignments. The benefits start to show in the 100 kloc and above magnitudes, and as there are so many ways to paint yourself into a corner with bad overall design, coupling, unmaintainable (or, my pet peeve, slow) tests, chances are, you don't figure out all the necessary things yourself. On top of that, there is no time to learn this much in most dev jobs, so you are left to learn with hobby projects (which do not usually grow big enough).
Most TDD experiments result in failures for the reasons listed. This is why you read so many comments on TDD being useless, wrong, a religion, or Uncle Bob cult. However, it seems that people who keep practicing TDD have been programming for more years than people who have not tried it, or have abandoned the practice. I have yet to meet a TDD practitioner who started programming that way and has not considered any alternatives. The ideas have born out of really bad - serious - experiences with existing approaches.
Re: Ask HN: Help me see why everyone seems to love TDD?
#66TBH, I don't know anyone who does TDD. I only know a few handfuls of developers, but so far the only people I've briefly met that do TDD were ones selling it; the consulting company that came into the company I worked for. This consulting company tried to "teach" us TDD at the same time as I think they were learning it. Not a single developer out of the ~40 on our teams bought into it, because in almost all cases the…
> TDD is a bit like waterfall, in the sense that you're assuming you know what the code needs to do before you write it Very true; but there are cases where you actually have that knowledge. If you are asked to port some application to another framework or language, and have tests, I'd highly recommend you use them. I have been refactoring an ETL pipeline (to offer extensible, more flexible behavior) that sort of gre…
Absolutely, but that's not TDD.
The old tests (presumably) were written as regression tests, and code changes must comply to the (hence) regression tests' expectations. That's perfectly reasonable, and I think that's most tested software projects operate.
Re: Ask HN: Help me see why everyone seems to love TDD?
#67TBH, I don't know anyone who does TDD. I only know a few handfuls of developers, but so far the only people I've briefly met that do TDD were ones selling it; the consulting company that came into the company I worked for. This consulting company tried to "teach" us TDD at the same time as I think they were learning it. Not a single developer out of the ~40 on our teams bought into it, because in almost all cases the…
I did a new "production" project where I did full TDD. Ended up with about 200 tests. As things go, specs changed and part of this application had to be rewritten. Most of the tests started to fail, not because the code was wrong, but because they tested for different spec. So I needed to rewrite all those unit tests again. Sure, I catched "some" refactoring bugs, but most failed tests weren't bugs, just tests that b…
Re: Ask HN: Help me see why everyone seems to love TDD?
#68However, I have found that much of the TDD approach needs to be tweaked to the requirements. TDD can become a huge overhead - and overheads don't get maintained.
For example, when writing an API service - the endpoints are important and expected to work correctly. Yeah we need to test those specs with tests. But the API endpoint might call 10 different methods within the code. But TDD will mention each method should be tested - this is where the overhead begins. And then people are very opinionated about how to define a unit/method. When TDD focuses on code-test-driven-development instead of functionality-tests-driven-dev, the overheads add up significantly. (NOTE: I am not at all discounting the benefits of code-testing and code-coverages. Just saying these tend to be value-enabler-overheads that many times yield very little)
The #2 benefit for developers is ability to develop faster. However non-TDD devs will not immediately buy into this and will need quite some practice before they reap benefits. Also I have noticed certain kinds of projects are better off starting without TDD and introducing tests benefits only after the code grows to a xyz size (and when refactoring makes sense). If it was an application without unit-tests, I wouldn't try to fix it. However, I would write tests to make sure application performs in a certain way in a sandboxed environment - even if it meant testing the functionality via some headless browser.
Re: Ask HN: Help me see why everyone seems to love TDD?
#69Re: Ask HN: Help me see why everyone seems to love TDD?
#70It's more culture than anything else. People have been testing code for years and years, and people will keep making ways to organize teams, workflows, and every half decade a new Bootcamp, Redmine, Asana and Jira will come out.
At the end of the day, you have to have something in place. The bigger your team is the more you need it.
TDD is simply one school of thought for how to ship less bugs.
Some people do it, most people do not do it strictly.
Most of the teams I work with this day and age are no longer very strict on TDD because for their specific products they are shipping it slowed down development enough to notice.
But some people love it and some people I think it may make faster.
Personally I look at it as a way to solve a problem, likely when assembling a new team. If you don't have issues with speed and quality and coordination then I wouldn't try to add TDD. But if you do it's one of a handful of potential solutions , and depending on your team and product may or may not be a solution.