4 ms·
Maybe the title should be: TDD did not live up to my expectations? I too, like the author, have been practicing TDD for > 10 years. Test, implement, refactor,
by agentultra 9y ago
Maybe the title should be: TDD did not live up to my expectations?
I too, like the author, have been practicing TDD for > 10 years. Test, implement, refactor, test... that's the cycle. If you follow that workflow I've never seen it do anything to a code base other than improve it. If you fail on the refactor step, as the author mentions, you're not getting the full benefit of TDD and may, in fact, be shooting yourself in the foot.
I've read studies that have demonstrated that whether you test first or last doesn't really have a huge impact on productivity.
However it does seem to have an impact on design. Testing first forces you to think about your desired outcomes and design your implementation towards them. If you think clearly about your problem, invariants, and APIs then you will guide yourself towards a decent system.
The only failing I've seen with TDD is that all too often we use it as a specification... and a test suite is woefully incomplete as a specification language. A sound type system, static analysis, or at the very least, property-based testing fill gaps here.
But for me, TDD, is just the state of the art. I've yet to see someone suggest a better process or practice that alleviates their concerns with TDD.
- eropple 9y ago> Testing first forces you to think about your desired outcomes and design your implementation towards them. If you think clearly about your problem, invariants, and APIs then you will guide yourself towards a decent system. The way I put it: "if I don't know the domain and range of my function, I shouldn't be writing code yet, I should be investigating the problem." TDD is for unit tests, and unit tests best test functional, stateless code--the functional, central logic of your application is what you should be specifying and writing unit tests for, not all the imperative stuff wrapping it for IO and failure catching and the like (Gary Bernhardt[1] calls it scar tissue). [1] - https://www.destroyallsoftware.com/talks/boundaries https://www.destroyallsoftware.com/talks/boundaries
- tieTYT 9y ago> TDD is for unit tests Never heard anyone say this. Kent Beck has said the opposite on podcasts.
- eropple 9y agoI think it probably depends on what your definition of "unit" is. As I stress functional units that encapsulate logic and data model but don't permute state, my units are probably significantly larger (and simpler) than those of people writing more imperative/traditional-OO units (where something under TDD may encapsulate many units due to mounting complexity/complication and so require further decomposition).
- Retra 9y agoIf you don't know the domain/range of your function, and you are forced to write tests in advance, then you will end up specifying a domain/range. The worry here is that you pick a domain/range that is really inefficient, and you write 'bad' code to support it, and you can't refactor it out without more overhead later. Now, this is a minor issue. It's probably more worth it to build inefficient interfaces now and try to fix them later than to never build anything because you don't know what the optimal design is. I can't say if TTD gives a real advantage there, but when designing-while-coding-with-no-tests, you end up playing with the interfaces, changing them regularly, and learning something about why they are the way they are. Which is possibly a better process when you don't have any relevant design experience? I really don't know...
- gurkendoktor 9y ago> I've yet to see someone suggest a better process or practice that alleviates their concerns with TDD. I think that's part of the point. If you want to follow a process like clockwork, test-implement-refactor-test, then TDD might be the best we have. But what if not having any process is better than even the best formalised process? That's certainly my personal experience: my haphazard, process-free way of hacking delivers solid results very fast.
- HeroOfAges 9y ago"If you think clearly about your problem, invariants, and APIs then you will guide yourself towards a decent system." This is the most beneficial part of TDD to me. Most devs will deny this, but their biggest issue with TDD is not wanting to take the time to think clearly about a problem. To me that seems a bit sloppy and lazy. We're supposed to be professionals. From some of the comments I've read, it also seems that devs are trying to "test drive" or write unit tests for the wrong things. As I've gained experience as a software developer, I actually look for ways to write less code. The most effective way for me to do that, is to actually think about the problem before I write a single line of code. If I have a clear idea of what it is I'm trying to build, it's very easy for me to write a test first. If I can't identify a way to write a failing test, it's an indication to me that I really don't understand the problem well enough to deliver a dependable solution.
- dwaltrip 9y agoDo you use TDD on prototypes? Or other projects where the design is highly likely to change or be discarded?
- danthemanvsqz 9y agoI don't use them on prototypes because I will throw away that code. But IMHO TDD is at it's best when your design is highly likely to change. The only protection you have against a moving target is your test suite. The requirements or our understanding of the requirements change so we change the code. In large code bases we can only be certain that the code change doesn't break anything if we have good tests. TDD is the only realistic approach to achieve 100% test coverage. You can certainly write good tests to cover your code at 100% but I've never seen it done by anyone consistently without TDD.
- agentultra 9y ago> Do you use TDD on prototypes? Yes. > Or other projects where the design is highly likely to change or be discarded? I don't often just start writing code without thinking about the design of the system or module I'm working on. Unless I'm writing a one-off shell script or some simple elisp glue code... I write the tests first.
- draw_down 9y ago> Maybe the title should be: TDD did not live up to my expectations? That is the title. If you are arguing that explicitly specifying "my expectations" would significantly alter its meaning, I disagree. Otherwise, whose expectations were we to assume TDD did not meet?
- dragonwriter 9y ago> Otherwise, whose expectations were we to assume TDD did not meet? Without qualification, I would expect those of the people choosing to adopt TDD generally.
- nickpsecurity 9y ago"But for me, TDD, is just the state of the art. I've yet to see someone suggest a better process or practice that alleviates their concerns with TDD." Design by Contract specifying key properties at interfaces with tests for stuff not easy to specify was state of the art in the 90's. In the 2000's, there's tools to automatically generate tests from such properties or apply formal proofs to code if it's simple enough. I don't see TDD as either strongest method or state of the art. DbC, assertion/property-driven testing, some fuzzing, and proving /model-checking for most important components collectively seem state-of-the-art for realistic software. Most of which is just automated versions of manual methods invented in the 50's-60's. Most being 60's with fuzzing going back to 50's. One from later time I like since it consistently got low defect rate was Cleanroom. Here's a good explanation of it. http://infohost.nmt.edu/~al/cseet-paper.html http://infohost.nmt.edu/~al/cseet-paper.html
- agentultra 9y agoHey nickpsecurity! :) > I don't see TDD as either strongest method or state of the art. It's not the strongest method. But as far as the SWEBOK[0] is concerned it is state of the art. The most effective teams I've worked with layer their testing strategies and use multiple approaches to verification depending on the needs of the project. I love quickcheck. I even pull out formal methods when the problem domain demands it or I need to check my thinking. On the scale of "sketch on a napkin" to "verified and signed-off-by-master-engineer blueprint" I'd say a unit test suite, as far as it is a specification, is somewhere between napkin and the middle. If you use a soundly typed language AND a unit test suite using property-based assertions you're somewhere in the middle; building houses. However I do see it as a warning sign if a team actively avoids TDD and tries to ship the first thing that works. If I was an actuary that project would represent a high level of risk and I'd probably raise their insurance rates to match that risk depending on the work they're trying to do.