Live data from Hacker News

TDD did not live up to expectations

blogs.msdn.microsoft.com

361–370 of 450 posts

Re: TDD did not live up to expectations

#361
Would it still be TDD when talking about functional tests? So no mocking. Or does strict TDD definition only include unit tests.

Because the general principle of writing a test case and then writing/editing code still applies with functional / integration tests.

And I have always preferred to use functional tests to test bigger components / packages based on their public interface then to write a unit test every small function inside the package.

Unit tests seem to be much more useful in situations when you know exactly what should your inputs and outputs be, for example if you are writing a function to transform data from one type/object to another. This is where unit testing shines.

But a lot development usually involves integrating / gluing together several higher level components together and passing data between these components and I much prefer functional tests there.

Re: TDD did not live up to expectations

#362

Earlier quoted context omitted.

> TDD is this crazy religion of writing tests for everything, Not true in my experience. You should only test code you wrote that can break. You do not test core functionality, the OS underneath etc. You do not test the test themselves.

No, TDD means that if there is a line of code anywhere that was not written to make some failing test pass, that code is by definition broken. ALL code must be against some test, else it's not TDD. And if you want to write code for which there is no test, you must write the test first, run the test suite to see it fail, and then implement the code that will make the test pass. Anything else is not TDD.

Should you write tests for the tests too? What I find is that in any project of a certain complexity, the tests can end up having the wrong scope or outright bugs in them.

Re: TDD did not live up to expectations

#363
post #160

The main benefit for TDD in my mind is that it mostly makes it painful to write spaghetti code. When I'm reviewing something that looks too integrated, I just ask for a unit test for that particular piece of functionality, and the author is effectively forced to go back and refactor. After going through this a few times, they learn to think about their design before they write code. Of course, many dynamic languages…

TDD is about creating tests for your requirements, and then writing code to make them succeed. The reason it doesn't work is because most medium/large feature changes don't fully realize their scope and requirements until they're well along into development, making the earlier tests an unnecessary drag. Writing unit tests at all is independent of TDD. After you get the feature working, you write those to verify the p…

Fair enough. The benefit of TDD them in my mind is that it keeps undisciplined developers from wedding themselves to a bunch of untestable code and then getting frustrated when asked to add tests in a code review. Whether or not this is the stated purpose of TDD is a different matter.

Re: TDD did not live up to expectations

#365
post #362

Earlier quoted context omitted.

No, TDD means that if there is a line of code anywhere that was not written to make some failing test pass, that code is by definition broken. ALL code must be against some test, else it's not TDD. And if you want to write code for which there is no test, you must write the test first, run the test suite to see it fail, and then implement the code that will make the test pass. Anything else is not TDD.

Should you write tests for the tests too? What I find is that in any project of a certain complexity, the tests can end up having the wrong scope or outright bugs in them.

I keep asking the same thing, especially that given any non-trivial self-contained piece of code, the test code will necessarily be isomorphic to the actual implementation - at which point one has to ask, why bother with TDD in the first place and not just write the complex code once?

Re: TDD did not live up to expectations

#366
post #204

Earlier quoted context omitted.

> The main failing of TDD is the assumption that you know all of the tests that you will need before you know your software. You know what makes this work for me (I am a TDD & BDD dev, and I don't think it's dead) is the fact that you can reorder commits. When I hit a case like this, where the correct code is easier to write than the correct test, I still test it. I write the test after, then I reorder the commits on…

+1, that's a pretty cool idea >> I write the test after, then I reorder the commits once the test passes, and make sure it fails predictably in the way you were expecting it to fail.

Lol, that literally sounds like cheating. You write the code first, tests later, and then reorder the commits so that you can say to everyone (colleagues and managers) that you follow TDD...

Seriously, why bother reordering the commits?

Re: TDD did not live up to expectations

#367
post #309

Earlier quoted context omitted.

AFAIK, all of the TDD proponents would agree that lots (most?) glue code doesn't need to be covered by unit tests.

I think this is the result of code coverage metrics that are often advocated. When you need some arbitrary level of coverage you have to write tests for glue code. It may be different in dynamic languages, but in statically compiled ones the compiler does all the testing required for glue code.

> In statically compiled ones the compiler does all the testing required for glue code.

It cannot, for example, tell if you have glued things together in the wrong order.

...but a test of the glue code alone will not necessarily tell you that, and you will waste a lot of time mocking the lower-level functions to perform a standalone test on it. It is better to test an assembly as a unit, which will test the glue code (and give you a coverage count for it.) In many cases, it will also test your low-level code without you having to write so many mocks and harnesses.

I think you can find TDD zealots who insist that you have to write tests for every little piece in isolation, but this takes a lot of time, especially if you have to write a lot of mocks to do it (and testing with mocks is error-prone; the mocks may conform to your invalid assumptions.) There is never enough time to test everything, so excessive unit testing means giving up some potentially more informative integration tests. As in most aspects of development, good judgment matters more than strict obeisance to the rules.

Re: TDD did not live up to expectations

#368
post #47

And another generation of programmers learns that there is No Silver Bullet[1]. This will happen again and again. [1] http://faculty.salisbury.edu/~xswang/Research/Papers/SERelat...

Indeed, as long as there are people caring enough to seek out ways to improve their product/craft, there will be an ample supply of silver bullet merchants to satisfy the demand. Predictably with discussions along the same fault lines too (works for me, hate being forced to use it, you are doing it wrong etc.)

Re: TDD did not live up to expectations

#369
I grant the premise that TDD has drawbacks. But are they really worse than the drawbacks of not writing tests?

Code with no test coverage will have more defects and will be more prone to regressions.

For many projects TDD is the best we've got until something comes along that replaces it.

Re: TDD did not live up to expectations

#370

The main benefit for TDD in my mind is that it mostly makes it painful to write spaghetti code. When I'm reviewing something that looks too integrated, I just ask for a unit test for that particular piece of functionality, and the author is effectively forced to go back and refactor. After going through this a few times, they learn to think about their design before they write code. Of course, many dynamic languages…

Interesting that you mention dynamic languages. I think that a lot of why people do TDD is that you can't reliably know if a program in a dynamic language has basic issues unless you run it.

The same is partially true for manual memory managed languages.

You need to push towards 100% coverage in order to replicate the advantage you get in a statically typed language like Rust.

Post reply on HN