It's OK Not to Write Unit Tests
blogs.msdn.com
blogs.msdn.com
"If you're a Java programmer and want to have a rude awakening, go download Jester. Jester is an automated mutation testing tool - it goes in and replaces "<=" with "<", "&&" with "||", "!" with whitespace. And then it re-runs the tests. And then you get to watch in horror as your tests still all pass, regardless of what the product code actually does."
Not a fan of unit testing my self. I feel the approach lacking.
I'm not arguing against unit tests, they definitely have a time and a place. I'm just not convinced that they are an easy and instant cure for all your hardest bugs.
An example:
int fun(int a, int b) {
if (a >= b) {
return 1;
}
return 0;
}
now you could test this by saying:
fun(4,3) should give '1' as the output
and
fun(3,4) should give '0' as the output
But you'd miss to test for equality, with fun(3,3) which should *also* give 1 as output
So you'd need an extra test for the '=' part of the condition. Replacing '>=' with '>' will still pass the first two tests, so if you forgot about the third you will not even realize something is wrong until your code starts breaking in mysterious ways.Unit tests have to be just as good as the code you wrote.
http://glu.ttono.us/articles/2006/12/19/tormenting-your-test...
Heckle is a mutation testing framework for Ruby. I don't use it all the time, but my tests are definitely better now that I've tried it and seen what some of the edge cases are...
I fully agree, but I am getting tired of all of this slam down style, flame-bait headlined, writing.
There's this theory out there that Agile projects can refactor fearlessly because there's this immaculate suite of tests that can sound the alarm the second the smallest regression gets introduced. But anyone who's actually tried it knows that it's mostly just a fantasy.
Poppycock. My project has an extensive test suite that we rely on to make major design changes with alacrity, just exactly the way that unit-test advocates advocate. We couldn't dream of doing what we're doing without it.
It's true that not every module of every system responds equally well to this style of testing. It's true that putzing around revising test infrastructure for the nth time really sucks. But these are points that belong in a serious discussion, the kind that recognizes tradeoffs.
cashto emphasized that unit testing is useful for teams with non-expert programmers (viz. his comment about the Dreyfus model of skill acquisition). Many of us are non-experts who benefit from working with the TDD training wheels on; it's O.K. to be less a Jedi All-Star hacker. But the phenomenal programmers, the men and women who were 10 times better than me, could not be bothered with TDD, even through the endorsed it for mere mortals.
To paraphrase the TDD credo of “no test is worse than having no tests”, we can assert that blind faith is not better than no faith at all.
I also notice reference to writing tests after the fact. I understand TDD to involve writing tests first. That's how I practice it anyway.
My experiences are the same as yours. I've refactored code where the unit tests caught that the new structure introduced subtle logical inconsistencies in the program. The unit tests meant I caught this immediately; without them I would have had to wait until subtle and hard-to-fix bugs emerged.
On a different project, I've been able to play around with the structure of the code, secure in the knowledge that my regression test suite will tell me when I fuck things up.
Tests, when done well, are a lifesaver, and essential to any large complex codebase.
> But these are points that belong in a serious discussion, the kind that recognizes tradeoffs.
Exactly.
Here we see the risk of asserting something isn't real just because we haven't ourselves seen it. I've held a bat in my hands, and I've had my butt saved countless times by tests I've written.
However, I am quire pleased that this is a very sensible and mature position about unit testing (I think a short version would be: well, testing can help, it won't carry you and you have to stand on your own feet, but it can help), which is pretty close to my own position. Good Article.
Scaffolding includes dummy components, miniature file (minimal eg of a file format), "generators of test data, special analysis printouts, cross-reference table analyzers" (jigs and fixtures).
"It is not unreasonable for there to be half as much code in scaffolding as there is in product". I end up writing a lot of the above kind of code - not as automated unit tests, but just as a way to make sure my code is doing what I think it's doing - just plain ol' testing. It can feel wasteful, so it was reassuring to hear Fred's take.
Just don't overdo either way and you'll be fine.
The article mentions this problem too. The benefit of the tests disappear when your code changes beyond refactoring.
It requires a significant effort to make unit tests more efficient. This effort must then be balanced with the potential costs of the bugs and across the application, because some part of the program are more critical than others.
A good programmer should thus balance his effort in unit tests writing.
I also suggest to write unit tests as needed to be more efficient. If the software is a data processing pipeline kind, simply write a very tight data validity checks at the end of the processing pipe and inject test data (including bogus one). If no problem ever show up with the test data, there is no point in writing unit tests for all intermediate steps of the data processing pipeline. If a problem is later discovered, then write the test, but only at the middle of the processing pipeline. You'll know if the problem is before or after. Then continue as needed. With this approach, you'll write unit tests only where it is needed and won't waste you time.
Suggesting as the author that we don't need to write unit tests is like saying we don't need to put the car safety belt because people still die in car accident with it, and most of the time we don't have any accident even if we don't wear it. Is this a smart advise ? I don't think so.
BTW, I use asserts wherever I can by reflex in my code because it saved me valuable time on many occasions.
That's the point, and I think everything else in this article stems from it. Unit tests are supposed to be transient; you're supposed to be able to just ditch them and replace them when you ditch and replace the code they're testing.
Functional tests, on the other hand, should be longer-lived.
Once you've written enough of them, you kind of seem to develop an instinct as to what unit tests are useful for.
Obviously SQLite has got a tremendous amount of value out of unit testing. But SQLite is quite abnormal in many respects. It's used in aviation, so the standards of testing are ridiculously high. It's also a library, and libraries tend to be very easy to test. It's also a long-term project with no deadline to speak of.
Certainly, all his arguments downplay TDD in general
http://www.scottschulthess.com/coding/?p=143
Basically, there are other benefits to TDD than just preventing regression.
Documentation and ease of debugging while your writing code being the biggest ones.
In a non-compiled language it can serve to verify that your at least runs without gross failure a little like the compiler does.