I am skeptical of TDD, so I have a genuine question. Let's say TDD is able to find the "most obvious" bugs, like a typo. My question is, why are these bugs worth creating a test for them, compared to either manual testing (running the program and looking at the output) or running a portion of the integrated test suite on the code to find them? If the bug is simple and crippling, then the program is likely to fail anyway.
To me there is a tradeoff. With TDD, you write some unit test code, and it finds a trivial bug. But is every trivial bug found worth maintaining the unit test code going forward? I mean it's not like this bug is gonna appear again all of sudden in your code, unless you change it, but then in all likelihood you need to change your unit test as well.
I guess I don't really see TDD as a good tool, because all the situations that you can run into are already covered by other, more specialized tools. If you want to catch edge cases, asserts are IMHO superior tool to tests. If you want to verify your program quickly, running it manually and looking at the output is superior. If you want to verify your program properly, running a comprehensive (and integrated) test suite is superior (the best if you can make it property-based).
There are situations where unit tests are genuinely useful, like writing a library. But in those cases, unit tests seem to always either compare with some other implementation (for example, if I am testing a sin(x) function, my other implementation is the calculator), or at least compare with well-defined specification that comes outside the code. But I feel like majority of tests written for TDD are not really testing the code against anything (simply because another implementation or specification is not available), they just test the intent of the code itself as is written, which might be useful if you wanted to write "bar" but wrote "baz" by accident, but other than this type of bugs, what is their long-term contribution, that could justify the maintenance cost?
TDD tests would ideally be used for hunting business value, and focus on overall desired product behaviour and qualities.
I don't think it really helps software development, if instead of "here's the description of what we need to do" the SW developer gets "here's a few examples of what we need to do" (albeit if the examples can be automatically verified).
If that's NOT your intent, what's the role of specification in the TDD, and how it's interacting with the implementation and the tests?
That's pretty much it. The value is that tests can be automatically executed and verified. A specification document can't.
Writing a spec is still a step in the process - a bootstrapping step. The spec is a "write one to throw away" placeholder until you get far enough that the spec can be replaced with executable tests.
My take on specification is that you encode it to be executable as your program, during development. Ideally, the program should encode the specs in the most straightforward way possible. To "specialize" the spec into tests first and then "generalize" it again from tests into a working program seems like unnecessary hassle, and frankly prone to information loss.
It's interesting, because as I state in another comment, I have a big disagreement with a guy who loves TDD. I guess I am a theorist (I derive my feeling of correctness from simplicity of the code) and he is an empiricist (he derives his feeling of correctness from many small tests), and it somehow defines our approach.
The adherents really want tests to be the specification, as a way to be measurable / testable. Specs may be converted to tests.
But most of it is theory. It all depends, as usual, on the dev(s) and circumstances.
The barrier means QA doesn't have the same model, and often lacks info that you have. That's valuable in some aspects, but it's not double-entry. (Double entry in accounting means that you always record two transactions that need to match each other, not that there's independent verification - that'd be auditing)
I believe you need both double-entry and independent verification. (Of course, that depends on scope & desired quality. Your 100-line bash script that you only run to print fortunes for your friends probably needs less rigor than products that are used by billions, or that have life-or-death impact)
You're right that it's not specifically TDD that enables this - but you do want automated unit tests written by the developer, whatever methodology you use. (Or at least I want them :)
Unit tests still help of course with static typed languages but you really don’t need to be afraid that refactoring can kill your entire code base as you have formal proof that types and names agree as part of your IDE and build process by default.
The obvious bugs should already be accounted for if you have decent param checking in most functions. Is the string empty? Is the array nil? Did the init succeed?
Inline unit tests anyone? :-)
> I and everyone I have ever talked to about testing has had the same experience; we write a new feature, test the hell out of it, can’t find anything wrong; ask a coworker to take a crack at it, and he finds a major bug in under a minute. The password is blind spots, and we all have them. And if we didn’t think of some case in development, we are not going to think of it in testing. That’s why we had separate QA departments.
I wouldn't go as far as the author saying TTD is useless as it's genuinely useful against most obvious bugs, but it's only a a part of the equation. But it's not like all companies removed their QA departments either - many pieces of software are regularly tested by independent teams with good results. If someone thinks TTD will eliminate all bugs, well, they're not thinking clearly.