Live data from Hacker News

Ask HN: I'm less productive with TDD. Am I doing it wrong?

news.ycombinator.com

1–10 of 24 posts

Ask HN: I'm less productive with TDD. Am I doing it wrong?

#1
Hi guys,

I've been programming for about four years now. I was taught on the job by a friend, and I've always learned to make one small piece before connecting everything

For example, if I need to make a simple 2D game, I put together the rendering function, then a separate function for handling key-events etc.

The gist is that I don't really have a blueprint on paper, it's all in my head, the blueprint comes together when I glue everything together.

I've been taking an introductory programming course and it's been asking me to jot out every function I need, all the variables, and write all the tests before hand before implement the actual code. I've been finding this challenging. I've not found a case where writing tests actually helped with writing the program. For me, it's been a hindering process. Am I doing something wrong here?

Re: Ask HN: I'm less productive with TDD. Am I doing it wrong?

#2
I think the problem is that you have an incomplete understanding of what it means to be productive.

Your programming course seems to be discussing an extreme and possibly excessive version of TDD. I have written a lot of code, and I like TDD, but in moderation. I certainly do not test every single function using TDD. I do not work out my functions in advance. However, I do take care to design and document major interfaces between components. I will write tests against those interfaces. For non-trivial parts of my code, I will write tests for smaller components. I do not take it all the way down to every function, that's nuts.

Now these tests do take time to write. And if you measure productivity by lines of code written per unit of time, well your number will go down. But that's the wrong measure. TDD increases my confidence that the tricky bits of my code are correct. It definitely catches bugs early, which is a huge productivity benefit. (And when I encounter a bug not caught by TDD, that I catch later, I will always write a new unit test to reproduce the problem.)

TDD also frees me up to clean up and refactor my code, and add new functionality. Since I have code that passes a lot of tests, I can change code with confidence because I know that the tests will pick up nearly all breakage caused by my change.

I will say that TDD has its limits. I find that TDD has been a dismal failure when the thing I'm testing has a dependency on some complex external thing, e.g. a service or a database. If you try to "mock" that external thing, you end up wasting tons of time debugging your mock database (for example). Also, external things with state (like services and databases) don't really fit TDD which depends on fast setup and teardown. Once you have these external dependencies, you are better off writing system tests.

Re: Ask HN: I'm less productive with TDD. Am I doing it wrong?

#3
A few things: 1. Proper TDD cycle is to write a single test and then make it pass. Maybe you write a acceptance test followed by a unit test; make the unit test pass; run the acceptance test; write more unit tests; and make them pass as well till the acceptance test passes. Writing all tests upfront deprives you of design feedback from your tests.

2. Even TDD done right has the most productivity benefits in the long run not short term. Your code base will be more maintainable because it will be more decoupled and you can refractor with confidence. In the short term you are faster without it.

Edit: I cannot recommend reading "Growing Object Oriented Software Guided by Tests" enough.

I also recommend watching some of Justin Searls stuff.

Re: Ask HN: I'm less productive with TDD. Am I doing it wrong?

#4
The problem with TDD is that if you have a lot of tests, then when you want to change your code you have to change a lot of tests. This leads to inertia against changing your code, and then ultimately when you do need to change things, you end up just rewriting your tests so that they pass to match the new code, i.e. the new code becomes the test.

Re: Ask HN: I'm less productive with TDD. Am I doing it wrong?

#5

The problem with TDD is that if you have a lot of tests, then when you want to change your code you have to change a lot of tests. This leads to inertia against changing your code, and then ultimately when you do need to change things, you end up just rewriting your tests so that they pass to match the new code, i.e. the new code becomes the test.

That's why it's important to have the majority of your tests be true unit tests that use doubles for their collaborators and have your classes adhere to single responsibility principle and open closed principle. That way you should only have to adjust very few acceptance tests.

Re: Ask HN: I'm less productive with TDD. Am I doing it wrong?

#6
post #2

I think the problem is that you have an incomplete understanding of what it means to be productive. Your programming course seems to be discussing an extreme and possibly excessive version of TDD. I have written a lot of code, and I like TDD, but in moderation. I certainly do not test every single function using TDD. I do not work out my functions in advance. However, I do take care to design and document major inter…

You nailed it. Mocking data while testing is such a pain. Takes the fun out of writng tests.

Re: Ask HN: I'm less productive with TDD. Am I doing it wrong?

#7
It sounds like the projects you've been working on have been pretty small; it's not always the case that you'll be able to hold all, or even most, of the pieces of a real project at once. Programming courses have to give you toy projects for time and scope, but should try to instill habits that will serve you when you start working on something real and complex.

Re: Ask HN: I'm less productive with TDD. Am I doing it wrong?

#8
My experience is that the advocacy of TDD in introductory programming courses is leading people to think that the way you test software is with unit tests only. It's not, by far the most important mode of testing software is manual testing: test out your changes as you make them and ensure that the thing appears, at least superficially, to be acting as it is supposed to. There is no point beavering away at unit tests when the thing doesn't even vaguely do what it's supposed to do in manual testing.

Re: Ask HN: I'm less productive with TDD. Am I doing it wrong?

#9
post #2

I think the problem is that you have an incomplete understanding of what it means to be productive. Your programming course seems to be discussing an extreme and possibly excessive version of TDD. I have written a lot of code, and I like TDD, but in moderation. I certainly do not test every single function using TDD. I do not work out my functions in advance. However, I do take care to design and document major inter…

> which depends on fast setup and teardown

In postgres at least, Wouldn't your framework create a db transaction that then is rolled back at the end of the test?

Re: Ask HN: I'm less productive with TDD. Am I doing it wrong?

#10

My experience is that the advocacy of TDD in introductory programming courses is leading people to think that the way you test software is with unit tests only. It's not, by far the most important mode of testing software is manual testing: test out your changes as you make them and ensure that the thing appears, at least superficially, to be acting as it is supposed to. There is no point beavering away at unit tests…

For things that have a clean interface, isn't it better to write a higher-level integration test rather than relying on manual testing?

Or at least to write an integration test to mimic the manual test so that you can refactor without having to correctly remember what manual test you did?

Post reply on HN