Live data from Hacker News

The Failures of "Intro to TDD"

blog.testdouble.com

61–70 of 85 posts

Re: The Failures of "Intro to TDD"

#61
post #9
post #3

The more I try to explain TDD, the more I realize that some of my favorite concepts, like the ability to mock functionality of an external process because the details of that process should be irrelevant...is just beyond the grasp of most beginners. That is, I thought/hoped that TDD would necessarily force them into good orthogonal design, because it does so for me...but it seems like they have to have a good grasp o…

This was indeed my motivation for writing the post. I think the next step to take if you agree with my premise is that we need to come together with ideas for how to best teach TDD to beginners/novices. Exercises that promote these concepts, lines of reasoning to take, tools to get people started without any unnecessary cognitive overhead, etc. I agree that teaching TDD exactly how I do it today can be a bit overwhel…

One thing I do with my beginning programming students (since their programs are tiny) is make them write out "test plans" on paper before they can write their program code.

They have to write the inputs and then the expected results.

It gets them thinking about the concept of using tests as part of the design practice.

Later, I give them the unit tests and they have to write the code. This is usually a rewritten version of a previous program so they see the text-based test plans in action as unit tests.

Then I might give them the empty test and an empty implementation, asking them to fill in the test first, then the implementation.

Finally I ask for a completely new feature, and they have to figure out how to write the test. And I ask them to go about it with a test plan.

After a few semesters of this, I think I'm ready to say that this is successful for getting the "beginners" there.

It doesn't address everything, but I think it's a good start.

Re: The Failures of "Intro to TDD"

#62
post #47

Earlier quoted context omitted.

fair enough. Do you think TDD and OOP are mutually exclusive practices?

TDD as I practice it does, but I think OOP as it's traditionally taught encourages developers to tangle mutable application state and behavior, which leads to all sorts of problems. The more I practice, the more I learn that life is better when I separate whatever holds the state from whatever has the behavior

> life is better when I separate whatever holds the state from whatever has the behavior

If you are not doing what is traditionally taught as OO, and you are doing something better why not say that?

I wonder why you don't say: "OO is an inferior design because it tangles mutable state with behavior"

"Not OO" should not be pejorative. OO is definitely sometimes wrong.

Re: The Failures of "Intro to TDD"

#63
Hey HN, I just wanted to thank you for the overall very positive, constructive comment thread. Thanks to you this post got roughly/over ~22k page views and I didn't receive a single vitriolic comment or bitter dissent. All I got was thoughtful, earnest, and honest replies. Made my day.

Re: The Failures of "Intro to TDD"

#64
This is probably the first reasonably sophisticated attempt to describe a test-driven design/development process I have read.

The observation that "[s]ome teachers deal with this problem by exhorting developers to refactor rigorously with an appeal to virtues like discipline and professionalism" reminds me of E. O. Wilson's remark that "Karl Marx was right, socialism works, it is just that he had the wrong species."

If test-driven design were the programming panacea its proponents sometimes seem to make of it, Knuth would have written about it in TAOCP. Instead Knuth advocates Literate Programming. TDD seems to attract a cult-like following, with a relatively high ratio of opinion to cited peer-reviewed literature among proponents.

TDD as this is commonly understood seems to me like the calculational approach to program design (c.f. Anne Kaldewaij, Programming: the derivation of algorithms), only without the calculation and without predicate transformers. Still it can be a useful technique.

There is no "right" way to program. This was evident from the beginning, when Turing proved the unsolvability of the halting problem. (Conventions are another matter.)

Re: The Failures of "Intro to TDD"

#65

Earlier quoted context omitted.

If you find yourself completely unable to articulate a test for something, you probably don't really know what it is you're trying to build. I don’t buy this argument. How would you write tests to drive the development of a graphics demo, say rendering a Mandelbrot set? Or a tool to convert audio data from one format to another? Or any other kind of software where the output doesn’t consist of readily verifiable, dis…

Are you asking about unit tests or acceptance tests? The problems you describe are very high level, but we could design an acceptance testing scheme for them. For the Mandelbrot set it might involve comparison to a reference rendering, for the audio tool a reference recording. In both cases you'd allow a delta relevant to the application, and probably also benchmark for acceptable performance. But my point was more a…

Are you asking about unit tests or acceptance tests?

I suppose what I’m really asking is how you would go from not having software to having software that does those things, using TDD. I think in practice its fail-pass-refactor cycle is normally applied at the level of unit tests, but in any case, how would using TDD help to drive a good design, to ensure testability, or otherwise, in that kind of situation?

(I’m asking this rhetorically. I don’t think TDD is a very helpful process in this context. I’m just trying to demonstrate this with practical examples rather than bluntly stating it without any supporting argument.)

Re: The Failures of "Intro to TDD"

#66

The comments section today looks like a support group for beginners/intermediates who struggled with TDD and gave up, and so want to explain why it's all bunk. I get this. I am not a great programmer. I'm self taught like a lot of you. I had tremendous difficulty grokking TDD and for the longest time I'd start, give up, build without it. But, I'm here as a you-can-do-it-to. You might not think you want to but I'm so…

"If you're struggling to write tests, and they're hard to write, messy, take a lot of setup, are slow to run, too tightly coupled etc. you have a design problem."

This is my problem exactly, and I wouldn't say I have a design problem. My application is a Django app that return complex database query results. Creating the fixtures for ALL of the edge cases would take significantly longer than writing the code. At this stage it is far more efficient to take a copy of the production database and check things manually. It helps that my app is in house only, and so users will report straight away when something isn't working.

But to say that I have a design problem because tests are going to be difficult to implement is just plain wrong.

Re: The Failures of "Intro to TDD"

#67
post #22

I have tried many times to do TDD. I find it extraordinarily hard to let tests drive the design, because I already see the design in my head before I start coding. All the details might not be filled in, and there are surely things I overlook from the high-up view, but for the most part I already envision the solution. It's difficult to ignore the solution that is staring my brain in the face and pretend to let it ha…

Maybe you're over thinking it? It sounds like you're already doing the right things. All the details might not be filled in, and there are surely things I overlook from the high-up view, but for the most part I already envision the solution. The design part of TDD is just the expectations. So if you were to test an add function for example, you might write something like assertEqual(add(5,2), 7) assertEqual(add(-5,2)…

Why is that TDD examples always test stuff that is pretty much useless? I don't need to check an add function. I am pretty confident it will work as is.

If you can find me a more useful example on somewhere then please show it to me.

Re: The Failures of "Intro to TDD"

#68
post #33

Excellent post, I've had exactly the same experience and come to exactly the same conclusion. I still follow the old Code Complete method: think about the problem, sketch it out, then finally implement with unit tests. The results are the same, and it's a lot less painful than greenhorn-TDD.

Time at a white board breaking down a problem is rarely wasted :)

I completely agree with this. I fact when I have a bigger architectural problem to think about I like to sit on it for a day or two, thinking about one or two designs that would work. It takes a while to see the strengths / flaws in each design and jumping in to code you won't realize problems until you have something half implemented.

Re: The Failures of "Intro to TDD"

#70

Earlier quoted context omitted.

Are you asking about unit tests or acceptance tests? The problems you describe are very high level, but we could design an acceptance testing scheme for them. For the Mandelbrot set it might involve comparison to a reference rendering, for the audio tool a reference recording. In both cases you'd allow a delta relevant to the application, and probably also benchmark for acceptable performance. But my point was more a…

Are you asking about unit tests or acceptance tests? I suppose what I’m really asking is how you would go from not having software to having software that does those things, using TDD. I think in practice its fail-pass-refactor cycle is normally applied at the level of unit tests, but in any case, how would using TDD help to drive a good design, to ensure testability, or otherwise, in that kind of situation? (I’m ask…

I think I mostly agree with your larger point, but I'm not in love with your examples. The Mandelbrot set does consist of readily verifiable discrete data points, after all. I don't have any problem imagining myself developing a Mandelbrot set program using TDD.

A great example for your point (which might have been what you were getting at with the audio thing) is a test for creating files in a lossy audio format. The acid test is if it sounds right to a human being with good ears, I've got no clue how you would write a pure computer test for that.

In my own work, a great example is finding a NURBS approximation of the intersection of two surfaces. There are an infinite number of correct answers for a given pair of surfaces, and testing that the curve you've generated fits the surfaces is a distressingly hard problem.

Post reply on HN