9 ms·
I have to to disagree. Tests _promote_ good coding behavior. Yes, people can circumvent them. Yes, people can write terrible tests. Yes, people could theore
by ergothus 11y ago
I have to to disagree.
Tests _promote_ good coding behavior. Yes, people can circumvent them. Yes, people can write terrible tests. Yes, people could theoretically write great code without tests (but most won't).
But if you're doing TDD with the intention of doing it right, you'll find code smells early, you'll tend to write things in a more change-tolerant way the first time, and you'll get some extra confidence in your code.
There's a reason switching to TDD from not using tests takes time and effort (general estimates say 6 months before you reach previous productivity levels) - this is the time in which you learning to code better. After which, your productivity tends to exceed your previous values.
I went through this a couple of years ago when TDD became something that moved from "it sounds cool but I don't have time for that" to something I could really do. It was hard to learn, but in the end I found that instead of writing code to pass tests, I wrote code that I liked, and the tests promoted those skills/behaviors.
Much of the pain people have from writing tests (in my limited experience) stems from:
* They are trying to write their tests after writing the code, and while their code may be "okay", it's not as free of side effects and external state as it could be == hard to test.
* Poor general education as to HOW to write good tests. I recall a few weeks where I tried to reconcile advice from person who said "don't have tests for simple existence" and another that said "write tests as you code". Eventually I figured out that the red/green/refactor cycle means you CAN and SHOULD delete redundant tests, but there's no reason not to write them as you start.
* Tests can be hard for exploratory code. Again, this experience. Once you find the proper balance, tests are not only NOT a cost, but a BENEFIT.
- joeld42 11y ago"After which, your productivity tends to exceed your previous values." Really, this is the only bit that I disagree with. Tests do promote good code behavior, and they can be useful for certain cases (another poster mentioned math libraries, which are a good case for them.) And they are good for learning how to code and learning to identify "code smells". But once a programmer has learned those skills, maybe they can stop wasting time writing tests. In my experience, the real productivity gains from unit testing are less than the productivity drag from writing and maintaining the tests. Not to mention the upfront cost of bringing a messy codebase under test. Tests also often require contorting your codebase in weird ways to make it testable. Sometimes this is an improvement and makes things more modular, sometimes it's just adding layers and indirections for no real reason other than "testability". If your codebase is breaking all the time, you've got problems. But maybe those problems are sloppy programmers, lack of code review and badly designed codebase. Unit testing is one way to address those problems, but discipline, experience, code reviews, firing bad coders, mentoring and not being sloppy are other ways that are often overlooked. Every team and organization varies, and if unit testing works for you, great. I just feel like it's becoming dogma, rather than simply another tool or strategy.
- ergothus 11y agoI think we'll just have to agree to disagree. In my (personal, anecdotal) experience, you might be able to get away with rely on skills encouraged by tests without tests much of the time, but when a test fails that I didn't expect because I made a small change, and reveals I had a false assumption, I'm saved hours of going the wrong way, because without the test I'd likely have not noticed the unexpected bug until after I added a lot more code. When it was discovered, I'd have no idea which section of code caused it, and because I clearly hadn't anticipated the problem, it won't be my first guess either. Similarly, when I need to make a quick last minute change, the tests give me much more confidence that there are no unintended impacts. I don't know how to rate that confidence, but it's definitely worth something. Lastly, tests serve as the ultimate API documentation for me. I have a terrible memory, so when I return to code I've not touched in months, I'm usually a bit lost. The tests tell me exactly what I want to know: what the code does, how to call it, and specific requirements that are on it. So I'm more able to switch around my code with confidence and less spin up/task switching time. (And I'll admit, this is not a highly transferable benefit of tests - Of my coworkers, I can only think of 1 out of 5 in the last two years where I gained the same benefit from their tests. I pin this on the poor education regarding the real details of writing tests, but it might just be that the tests as are personal as some comments: Where I write exactly what future me will need, future someone else will have different needs) All of that said, we completely agree that blind dogma without true understanding is just meaningless rote. To tie it back to the OP, he mentioned that he didn't shoot for 100% test coverage, but instead for where he found value in having tests. I'm likely far closer to that 100% coverage than you are, but if we're both making our choices based on experience and consideration, we're doing a lot better than some others.