Live data from Hacker News

TDD did not live up to expectations

blogs.msdn.microsoft.com

131–140 of 450 posts

Re: TDD did not live up to expectations

#132
post #120
post #96

Earlier quoted context omitted.

You are still writing the tests first, with no real learning from them other than "they are now passing." It is thought this is like engineering. You design an experiment and then pass it. However, that is not how experiments work. You design an experiment, and then you collect results from it. These may be enough to indicate that you are doing something right/wrong. They are intended, though, to be directional learn…

You can throw away the test if you don't find value in it. This can be very useful for fleshing out an idea.

But this advice should be extended further. Always be willing to throw away the code and the tests. Take the learning.

Be ware, though, that you are not throwing your customers for a bad ride. As soon as you have customers, it is nigh impossible to throw away the code without neglecting them. And they are your ultimate responsibility. Not the code.

Re: TDD did not live up to expectations

#133

No article about TDD, particularly one that shouts out to the respected Ron Jeffries http://ronjeffries.com/ , is complete without mentioning the TDD Sudoku Fiasco :) Ravi has a nice summary: http://ravimohan.blogspot.se/2007/04/learning-from-sudoku-so... Peter Norvig's old-fashioned approach is excellent counterbalance: http://norvig.com/sudoku.html

To be fair (and I'm no TDD fan personally), that mess wasn't really the fault of TDD at all. It was that Jeffries was learning how to write a Sudoku solver while he was writing his tests. If he started from Norvig's level of understanding, he surely could have written tests for an equivalently elegant solver quickly and simply.

Learning how to solve a problem by iterative coding (and throwing away the intermediate solutions) is a time-honored tradition that works very well. TDD may be an imperfect vehicle for doing that, but it doesn't really change the calculus.

Re: TDD did not live up to expectations

#134
One of the key benefits for me is the mindset (fostered by TDD) to make as much as possible of the code (unit) testable. This naturally leads to less coupled code, because otherwise it is not possible to test it in isolation. So the fact that you start with the aim of unit-testability leads to better designs.

Re: TDD did not live up to expectations

#135
post #96

Earlier quoted context omitted.

You are still writing the tests first, with no real learning from them other than "they are now passing." It is thought this is like engineering. You design an experiment and then pass it. However, that is not how experiments work. You design an experiment, and then you collect results from it. These may be enough to indicate that you are doing something right/wrong. They are intended, though, to be directional learn…

You're often learning the optimal API as well. I've had several experiences where I write a library, write some tests for it, and then realize that the library's API is inconvenient in ways X, Y, and Z, and that I could have a much simpler API by moving a few tokens around. When I write the tests first, I tend to get a fairly usable API the first time around, because I'm designing it in response to real client code.…

So, this is a slightly different mantra. Working backwards from the customer is an important thing. And if you know that customers will be using your product programmatically, then yes, building the API first is important.

But note, in that world, you aren't necessarily building tests of your software. You are building specifications for your API. I can see how these might be seen as similar. And for large portions of your code, they can be.

However, for the vast majority of your code, it exists to help out other parts of your code. Not to be used as a library/framework by others.

Re: TDD did not live up to expectations

#136
post #69

Earlier quoted context omitted.

> necessitate re-writing the test anyway, so why write it to begin with Because now you have an unambiguous record of the conscious decision to change your interface, because the test demonstrates the correct change of that interface. I don't write tests first for everything I do, but I try very hard to when I'm writing code that other people may read for this exact reason. Otherwise they have to divine my intent thr…

> the test demonstrates the correct change of that interface. No, they don't. Tests never prove correctness. They prove that assumptions are met. Whether or not those assumptions are correct is unprovable. The problem is, there are changes to interface that could make the entire approach of the existing tests completely meaningless. If all you're doing is changing the name of a method, that can be practically automat…

If there are changes to an interface that make irrelevant those tests, then you change those tests (and, if you're semantically versioning like you should be, you bump the major version number). I don't really get what you're objecting to. Implicit in doing TDD effectively is adopting the (light) burden of refactoring.

Yeah, people will delete tests because they refuse to refactor them. They're bad programmers. Don't work with them?

Re: TDD did not live up to expectations

#137
Test Driven Development? All these acronyms and not once is it spelled out in the article or the discussion! Is it like saying HTTP or DNS to most people? I'd honestly never heard of it...but the concept seems logical from a high level.

Re: TDD did not live up to expectations

#138

TDD failed for economic reasons, not engineering ones. If you look at who were the early TDD proponents, virtually all of them were consultants who were called in to fix failing enterprise projects. When you're in this situation, the requirements are known. You have a single client, so you can largely do what the contract says you'll deliver and expect to get paid, and the previous failing team has already unearthed…

> Software, as an industry, generally profits the most when it can identify an existing need that is currently solved without computers, and then make it 10x+ more efficient by applying computers.

>In this situation, the software doesn't need to be bug-free, it doesn't need to do everything, it just needs to work better than a human can.

Well said, these statements underscores importance of FINDING the PROBLEMS/TASKS that are done by HUMANS/MANUAL that can be AUTOMATED with COMPUTERS that can yield 10X efficiency .

Here are few gems from the original article https://blogs.msdn.microsoft.com/ericgu/2017/06/22/notdd/

The ability to write and refactor code to a state with low coupling, well-separated concerns > TDD Skills

1/ Design on the fly is a learned skill. If you don’t have the refactoring skills to drive it, it is possible that the design you reach through TDD is going to be worse than if you spent 15 minutes doing up-front design.

2/ I think that’s a good summary of why many people have said, “TDD doesn’t work”; if you don’t have a design with low-coupling, you will end up with a bunch of tests that are expensive to maintain and may not guard against regression very well.

Re: TDD did not live up to expectations

#139
post #82

Earlier quoted context omitted.

I've never heard TDD being that you write all of your tests up front, before you've written any code. I've always heard it as: When you're writing a class/unit, you write a few tests for what that unit is going to do. You then make those tests pass. You add some more tests, make those pass, and so on and so on.

> I've never heard TDD being that you write all of your tests up front, before you've written any code. That's the only way I've ever heard it described. I thought that's why it's called "Test Driven "

Can you provide a reference? I'm not a big proponent of TDD but have read up on it and experimented with it some, and none of the TDD literature I've read suggests writing all the tests up front. Virtually all the mainstream TDD literature and talks advocate for the "write a test, make it pass, lather, rinse, repeat" model of development.

Re: TDD did not live up to expectations

#140
post #33

Earlier quoted context omitted.

It doesn't necessarily lead you there at all. "Dependency injection" is a fancy phrase for "pass stuff a function needs into the function", only it does so by adding state to objects where that state probably shouldn't exist. You don't have to faff around with IoC or MVVM to properly isolate dependencies; indeed, it's the core idea behind something like Gary Bernhardt's "Functional Core, Imperative Shell" (which, if…

That's interesting although after a brief look it just looks like he is splitting the code into two parts, one part he tests and the other part he doesn't. I don't really disagree with this, my UI code has very few tests. "which, if you're not understanding this instinctively, makes me fear for your code" Thanks for the insult.

Sorry--that was a generic "you" there, not you-specifically. I'm saying that this is something everybody needs to understand because writing state-munging code is intrinsically harder to do correctly.

He's not just "splitting the code into two parts", though. He is consciously and specifically defining a core based on functional principles that avoid mutating state (which is harder to measure and reason about). That UI layer, his "imperative shell", is where state is managed, rather than embedding side effects into his business logic. (If you watch the Boundaries talk you'll see he frames larger applications as sets of functional cores surrounded by a layer of imperative routing between them.)

Post reply on HN