Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

A classic example of getting TDD wrong. Happens all the time.

TDD is about design, the article is actually criticizes unit tests. TDD helps you achieve SOLID principles, which really helps in real world. Fibonaccis, primes etc. are only for demonstration purposes.

And 100% coverage is for sissies, only a TDD noob talks about it in this context since it's not sane.



>And 100% coverage is for sissies

Depends on your project and the cost of failure. I once worked on a system that would automatically instruct semi-truck drivers to move their vehicles hundreds of miles. I spend over a week building tests for transactionality/concurrency edge cases to make sure that two trucks could not be instructed to go to the same place in error. Worth it? Yup. Should you test all possible behaviors of a utility script that, if broken, can just be re-run? Probably not.


It sure depends on the project type, I was talking about projects of HN people. For my site, for example, I have broken the signup process twice so I now have a couple of tests for it, unit + watin. But I won't bother with writing tests for, say, privacy settings.


If the demonstration programs contain problems (ie, the tests aren't good enough and the implementations contain unexpected performance and overflow problems, as I discussed), then why should I expected the practices to scale up to more complicated problems?

SOLID applies to OOD, and an essay I don't plan to write is why I consider OOD to be the wrong solution for most cases. In any case, my point is that TDD adds very little to the process of developing good software.

I mentioned several times that TDD provides weak tests and is insufficient to guide the development process. With examples. I did not criticize unit tests and I said that that's what I use in my own work.

The 100% coverage reference I gave comes from Kent Beck. I'm surprised that he's considered a TDD n00b.

You are more than welcome to reply in more detail.


I couldn't be able to pass the first steps of applying Scrum where I work for years, while web was flooded with positive experiences. Than, I met with a person with firsthand experience and found the flaw in my thinking, I was trying to follow everything in the book.

Some people combines Scrum with their existing process, some set 4 months iterations while others insists on not more than a month. Some can't live with a Scrum Master who is a part time developer. By the book, they all wrong. Yet, they're successful Scrum implementers.

So here's my account of TDD, regardless of what Mr. Beck said in the book (I am actually an Alt.Net follower):

Unit tests and TDD, for me, are totally different things. TDD is a way of construction, while unit tests are for inspection. Unit tests' re-validation power is great, but less and less needed if you have a good design overall.

Hence,

- TDD should not care to emphasize good test cases. It shouldn't even emphasize a complete test suite against a method. If someone want to test every possible way a function can be called, there are even automated software for doing it. It's a QA thing, not design.

- Worst case scenarios should be left to your test framework. Same as above. Row attribute in MbUnit. Range, Random, Combinatorial etc. attribute in NUnit (I'm from .Net world).

- No approach should give someone confidence that his code works all the time. Even the best QA can't catch all. But "When the bar is green, you know where you stand." means you are safe on what you test. If you test only for the correct input, you're safe for it. You'll know that missing inputs are untested. (Just a couple of unit tests, though)

- There's no 100% coverage. Since 100% coverage might also mean a <div>'s positioning. Screw it and all the UI breaks loose. Critical paths should be covered as much as possible (some 80/20 rule applies here. %20 of tests cover %80 of critical path etc.).

- When you want to change your api, do so. Write new tests, then a new api. The tests you have written are not part of your code real estate. Either feel totally ok for throwing them away, or don't use them. You will break your mental model of the old api when writing the new one without tests (we all write unit tests in our heads when coding), so what's wrong with breaking the digital representation?

- SOLID is nice, don't overuse OOD. But, what's wrong with having OCP everywhere all the time? Need OAuth? Extend your account service. Want to also publish to twitter from your app's main feed? Extend feed service.

Unit tests can be written good or bad. It depends on one's ability, testing framework in use, even the mocking framework. But in my experience TDD only improves your code, makes it more modular, more open to extension, more open to change.


I talked about TDD as a testing system and as a development system. You, like Beck, say it's only the latter, so I'll restrict myself to that aspect of it as well.

Worst case scenarios cannot be left to the test framework neither can good test cases. Leaving them out means the code is going to reflect an optimistic view of the requirement. A more pessimistic view may well entail extensive changes to the code, just like a more optimistic view may well be a lookup table if only two values are tested.

I never promoted the calling a function every possible way. In most cases that would take too long to be called a unit test. On the other hand, if there are only two possible ways then I would go ahead and do those as unit tests.

When I talked about "confidence" I referred to it as minimizing doubt. Other than a few cases of formalized testing or complete enumeration, I agree with you that you cannot be confident that the program works, if the interpretation of confident is "100% certainty." However, confidence has multiple shades of meaning, such as "I'm confident that I'll live to see 2010" when I know that that's not 100% for sure. In software the statement of confidence is more "I'm confident that the software is deployable with an acceptable risk and cost of failure." I don't think TDD leads to that level of confidence.

My position is like yours - 100% coverage is rarely worth the cost. I managed to get 99.8% coverage in a code base last year and failed to get 100% because I couldn't test two malloc failures without a day or two of additional work which clearly wasn't justifiable. My comment was the weaker statement that TDD does naturally lead to 100% coverage.

I wasn't talking about changing a developed API, my example was coming up with the API in the first place. If I develop the tests while I experiment with API and possible implementations then it's extra work with little benefit, and an obvious cost of time spent to develop those tests and modify them as the API changes.

What's wrong with OCP? As far as I can tell, what's wrong is the name. How is OCP different than "code reuse" and "reusable software libraries"?

I've just now done some shallow research on this. Meyer's original form promoted implementation inheritance, which is one of the forms of code reuse I've done. Martin's form of OCP promotes abstract interfaces, and I've grown prefer concrete interfaces. He specifically eschews public attributes and global variables, as being against OCP. I use them, but then again I also use Python, where these have different meaning than C++.

I'll also point out that Martin's form of OCP mentions "software entities" but really seems to mean "classes" based on the examples he gives. Template metaprogramming and Lisp macros seem to be two of many techniques that aren't mentioned in his discussions. For less esoteric topics, neither is Javascript code inserted into a web page during HTML template evaluation, nor dynamic code generation (eg, with LLVM), nor any place which takes an eval(). Those seem to be cases which can be quite useful and yet are counter to OCP.

As for your last paragraph, you've said that unit tests are totally different than TDD, but here you seem to say they are part of the same concept. My point is that good software development styles give the consequences you mention there. While TDD is one method people have used to learn good development technique, it isn't the only. Other development techniques must be learned, and these are not part of TDD as it's taught. My assertion is that TDD adds little to those techniques and as such isn't at best a weak concept.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: