TDD is nuts for code without a client or specification. The whole point of tests is to ensure that the code does what it's supposed to do. When you have neither client nor spec, how are you supposed to know what the code is supposed to do ? There is, IME, a >90% chance that any such code will be ripped out and replaced as you develop a better understanding of the problem domain. I've found it's pretty useful to go ba…
I've found the opposite, that TDD helps me most when the spec or my understanding of the spec is fuzzy, by forcing me to make decisions about behaviour up-front and clarify my thinking. Otherwise I can get bogged down trying to implement and specify a feature simultaneously, or spend a lot of time implementing a feature before realising I'm approaching it the wrong way.
Giving up on test-first development
171–180 of 224 posts
Re: Giving up on test-first development
#172Sometimes, but in my experience this is rare. Much more often, the easiest to code solution is both the hardest to test and to maintain, which is why having some TDD discipline more often results in better design, not worse.
Re: Giving up on test-first development
#173Earlier quoted context omitted.
One good way to the limit breakage in such cases is to solely perform black box tests on the API level. In case of our Node.js based Backends we don't ever write a single classical unit test, instead we have a custom Framework built on top of Mocha which performs tests on the HTTP layer against all of our endpoints. This works remarkable well in practice and allows for large scale refactorings under the hood with lit…
Of your tests break when refactoring, something is wrong. Probably, you're testing the implementation not the behavior.
Those kinds of "atrophied" tests can make a refactor considerably more painful than it should be.
Re: Giving up on test-first development
#174Earlier quoted context omitted.
That's kind of a waste of time if you're only going to run it once and verification with a REPL or otherwise by hand is easy enough.
That's assuming it works correctly the first time (I haven't had that experience often, even for "trivial" code :( ). Even for "run once" functions, I still use a few tests to develop them and make sure my expectations are correct. With a good framework, setting up a handful of unit tests takes just about as much dev time as running the function in a REPL.
What steps would you take?
Re: Giving up on test-first development
#175From the article: Because you want to ensure that you always pass the majority of tests, you tend to think about this when you change and extend the program. You therefore are more reluctant to make large-scale changes that will lead to the failure of lots of tests. Psychologically, you become conservative to avoid breaking lots of tests. Interesting. I've often found that the lack of tests leaves me absolutely terri…
Just because there are unit tests, doesn't mean they are covering all the code foremost, or that they are written properly to truly detect when things have changed for the worst.
Tests are not a replacement for actually testing and verifying your changes in whatever application gradient you're working in.
Re: Giving up on test-first development
#176I agree. TDD has it's places. Testing GUIs is often not one of them.
> You therefore are more reluctant to make large-scale changes that will lead to the failure of lots of tests.
Don't test private APIs. That makes no sense. I find quite the opposite. If I have more tests, I'm more comfortable making bigger changes, because of the safety net the tests give me.
> Think-first rather than test-first is the way to go.
Absolutely agree.
I think the "solution" to the TDD-or-not problem in Kent Beck-Martin Fowler-DHH [0] conversation was that TDD has it's places, sometimes it's really better than other and helps a lot, sometimes it just get's in your way.
Re: Giving up on test-first development
#1771) That having a test suite tends to makes a programmer conservative, to avoid breaking tests. But in a team environment, this kind of conservatism is a feature, not a bug.
2) That there are cases where the code that is easiest to test is not the best code. In my experience this is the exception rather than the rule.
3) That TDD causes the programmer to focus on the details rather than the overall design. This is a valid criticism, but the way to remedy it is to build prototypes and toy code before diving into the actual implementation. Here again, if you're a lone programmer working on a pet project, you're not going to see much distinction. But on a larger project with a team of programmers, such rapid prototyping is very useful. As they say, "build one to throw away".
4) The author has trouble designing tests for bad input. I'll take him at his word, but I've never found those kinds of tests to be that difficult; if anything, they tend to be boilerplate. Certainly when you're talking about validating complex input like JSON objects, it's not trivial, but there are libraries to handle most of those kinds of real-world situations.
Re: Giving up on test-first development
#178From the article: Because you want to ensure that you always pass the majority of tests, you tend to think about this when you change and extend the program. You therefore are more reluctant to make large-scale changes that will lead to the failure of lots of tests. Psychologically, you become conservative to avoid breaking lots of tests. Interesting. I've often found that the lack of tests leaves me absolutely terri…
One good way to the limit breakage in such cases is to solely perform black box tests on the API level. In case of our Node.js based Backends we don't ever write a single classical unit test, instead we have a custom Framework built on top of Mocha which performs tests on the HTTP layer against all of our endpoints. This works remarkable well in practice and allows for large scale refactorings under the hood with lit…
Re: Giving up on test-first development
#179From the article: Because you want to ensure that you always pass the majority of tests, you tend to think about this when you change and extend the program. You therefore are more reluctant to make large-scale changes that will lead to the failure of lots of tests. Psychologically, you become conservative to avoid breaking lots of tests. Interesting. I've often found that the lack of tests leaves me absolutely terri…
It's not a good argument against testing, I agree. Automated testing is a huge boon for software quality (though by no means a panacea). But TDD, in my experience, gives a slightly different dynamic. Because you generated the code being motivated by the tests, there are a lot of unit tests that don't test functional units - tests that are essentially testing implementation decisions. I've seen situations where that b…
There are a couple things to consider that sometimes become taboo in orgs--but shouldn't.
The first is that you don't need to test everything. I recommend having a great set of those API-level black box tests as an acceptance suite, but at a component or unit level you should pick your battles. If you'd architect for DI -only- to test, that testing had better be pretty necessary, otherwise you introduced complication (and risk) without a lot of benefit. That risk can actually overwhelm any benefit of testing.
The second is that you should absolutely scrap tests of implementation details at the point that the implementation becomes a black box. Tests are like scaffolding during construction, and we don't leave the scaffolding up when the building is done--we do inspections of the building instead. The same mindset should be applied to testing. Different phases need different tests, and too many tests at too low a level of abstraction absolutely cause maintenance and flexibility issues if you're not willing to let them go.
But that's no reason to back off entirely. SOME things need to be unit- or component-tested SOMETIMES. Those things generally benefit from TDD.
It's all about making intelligent decisions. There's a sometimes-controversial movement in QA/test called "context-driven testing" which comes down to there are very few always-best practices, and strategy should be tailored to your problem and situation--not done by rote, book, or prior (read, your boss's or CTO's) assumptions of what's always right. Otherwise you tend to get something more onerous than useful.
The considerations around that approach apply at the low-level test tier as well.
Re: Giving up on test-first development
#180I also think the benefits of testing have much more of a relationship to scale (both in terms of system usage/users, system complexity/size, development team size, etc.) and worst case failure risk that's often unacknowledged. (I don't suggest not having tests -- you'd regret that real quick. But I do think the appropriate level of test coverage can vary from project to project and component to component. Outer layers of onions probably matter, more, etc.)