The dangers of unit testing [modified]
-
I've been arguing for a number of days, trying to have shown to me any true value-added with a (so called) agile design methods, test-driven-design, and an acronym-based hell. I though myself as coding version of a Luddite. No More ! By and large, all the real work - the stuff that makes a program something useful, has to be done anyway. All that's really been done is moving the effort to a different location. And, it's monstrous: reading a simple database and creating the classes, (&etc of whatever it's doing) created 698 files. All of these are based on conversion of the basic tables into classes. The real coding has yet to begin! Another peeve with this donkey-dropping methodology is that the tests are supposed to replace the documentation. Another )&)$#&(^#$ excuse not to make the code readable to anyone else. What ever happened to just "knowing what you're doing and doing it right"? I think I'll end my rent and go out to watch the approach of hurricane Earl.
"The difference between genius and stupidity is that genius has its limits." - Albert Einstein
"As far as we know, our computer has never had an undetected error." - Weisert
"If you are searching for perfection in others, then you seek dissappointment. If you are searching for perfection in yourself, then you seek failure." - Balboos HaGadol Mar 2010
Be aware that I might be doing it wrong - just like almost everybody else. I agree with the notion that TDD is good for some projects, but not for all. However, there's no guideline for *what* project it would be good. So what's the point until we can tell at least that? Agile/TDD has some insights to offer: pair programming is more than lip service to the often repeated fact that people matter more than technologies. sprints - or however you call short cycles - can just mean coordinating changes so that you can deliver frequently. Automated unit tests do improve confidence in the code base. However, I see limits. There are many stakes to code - simplicity, maintainability, performance, extendability. Good design means that these go together - improving one also improves the others. Still, at some point, they start to work against each other. Testability is just another stake - for a long time, improving testability also improves other aspects, but it's nothing special, beyond that point you have to make tradeoffs. I have real problems with the "extreme" ends of TDD: I just can't write code that I know is wrong just to make a test pass. Frau Passig, commenting on capitalist vs. socialist economies, said very wise words: she just can't understand that any kind of planning - no matter how bad - can be worse that no planning at all.
Agh! Reality! My Archnemesis![^]
| FoldWithUs! | sighist | WhoIncludes - Analyzing C++ include file hierarchy -
peterchen wrote:
Agile Development - esp. Test Driven Design - seems to ride on a slew of assumptions that are completely ridiculous to me, e.g. Interfaces almost never change It's worth mocking databases, file systems, sound cards, external USB devices, analog test units (ok, I can mock Vista, that would already 80% of an OS) I can build an application from BankAccount, Stack and List. (seriously, have you seen any other example than one of these?)
I'm not sure that it does ride on those assumptions. Mocking can indeed be painful, especially if you're trying to mock something that doesn't have an interface already. And on the subject of interfaces, it is annoying when you suddenly have to extract a bunch of interfaces just to aid testability. It's kind of like going back to C++ where you have separate header files and source files - too many files and too much boilerplate "stuff". The last time I used mock objects in a Java test, it was very ugly thanks to the excessive syntax, but there's probably a much better way that I'm ignorant about. OTOH, to suggest that TDD assumes interfaces almost never change doesn't feel right. The whole point (to me) about TDD is to help in exploratory coding and to provide some level of confidence in the code you've written so far. And since I picked up the habit in 2006, I can tell you it's been a lot of fun (mostly) and that I still try to use TDD where possible (in Java and Ruby these days). Also, there's absolutely nothing wrong with testing after the code has been written - if you inherit a codebase on a project, there's a strong likelihood that it will be poorly tested (or totally untested). Writing unit tests and refactoring as necessary (as the OP seems to be doing now) is a superb way of systematically working your way through the code and understanding how and why it works. Sooner or later your unit tests start to look like little use-cases which describe and validate the API you're testing. Bugs are uncovered, redundancy is made clear, benchmarking becomes reasonably straightforward (if necessary). Win-win! :thumbsup:
destynova wrote:
to suggest that TDD assumes interfaces almost never change doesn't feel right.
My point exactly. I often go beyond these "no-go-areas" just to provoke by asking for rationales for obvious and accepted facts. My policy: Write unit tests for what can be unit-tested easily, forget the stuff that is hard. I don't trust anything that is preached as "if X is a problem for you, you should use more X".
Agh! Reality! My Archnemesis![^]
| FoldWithUs! | sighist | WhoIncludes - Analyzing C++ include file hierarchy -
OK, so for the last few days I have been writing a load of unit tests for some code that has already been mostly written (not wanting to be flamed for the obvious problem with this, just go with me here). The danger I am finding with these unit tests is that I am fast approaching a point where I would rather "refactor" so that I only have 1 method with a load of cut and paste code so that I have fewer methods to write tests for... [Edit: To the people telling me why its a bad idea to flatten the code like this, I did write *all* the original code myself, and do understand the point of methods and classes. I'm just fed up of this particular project, and no, actually it will not be me that has to maintain it, for reasons too complicated to summarise here :) ]
modified on Thursday, September 2, 2010 10:53 AM
I find using helper classes a good idea. The less cut n paste copied code out there the better. But don't put this cut n paste common code into inheritance heirarchies, then it becomes too complicated to morph. Less duplicate code the better. Use resharper. Tim
-
OK, so for the last few days I have been writing a load of unit tests for some code that has already been mostly written (not wanting to be flamed for the obvious problem with this, just go with me here). The danger I am finding with these unit tests is that I am fast approaching a point where I would rather "refactor" so that I only have 1 method with a load of cut and paste code so that I have fewer methods to write tests for... [Edit: To the people telling me why its a bad idea to flatten the code like this, I did write *all* the original code myself, and do understand the point of methods and classes. I'm just fed up of this particular project, and no, actually it will not be me that has to maintain it, for reasons too complicated to summarise here :) ]
modified on Thursday, September 2, 2010 10:53 AM
Talking about best practices for unit testing online is not easy because so many people are so easy to get on your case what you shoulda done, etc. So good job for having the balls to bring this forth. The issue that you're talking about is that of coverage, if think of coverage is executing lines of code with a particular program state. Whether a particular piece of production code is in a single method or multiple methods doesn't take away from having to write the unit tests that ensures the code is doing what it's supposed to do. Assuming you have 5 production methods, each of which can be easily tested with a unit test, then collapsing the 5 methods into 1 would not reduce the amount of test code. You'll still need those 5 unit tests, calling the one method now, with different parameters. But, now it may be more difficult to test.
-
Talking about best practices for unit testing online is not easy because so many people are so easy to get on your case what you shoulda done, etc. So good job for having the balls to bring this forth. The issue that you're talking about is that of coverage, if think of coverage is executing lines of code with a particular program state. Whether a particular piece of production code is in a single method or multiple methods doesn't take away from having to write the unit tests that ensures the code is doing what it's supposed to do. Assuming you have 5 production methods, each of which can be easily tested with a unit test, then collapsing the 5 methods into 1 would not reduce the amount of test code. You'll still need those 5 unit tests, calling the one method now, with different parameters. But, now it may be more difficult to test.