Live data from Hacker News

TDD did not live up to expectations

blogs.msdn.microsoft.com

181–190 of 450 posts

Re: TDD did not live up to expectations

#181

Maybe the title should be: TDD did not live up to my expectations ? I too, like the author, have been practicing TDD for > 10 years. Test, implement, refactor, test... that's the cycle. If you follow that workflow I've never seen it do anything to a code base other than improve it. If you fail on the refactor step, as the author mentions, you're not getting the full benefit of TDD and may, in fact, be shooting yourse…

> I've yet to see someone suggest a better process or practice that alleviates their concerns with TDD.

I think that's part of the point. If you want to follow a process like clockwork, test-implement-refactor-test, then TDD might be the best we have.

But what if not having any process is better than even the best formalised process? That's certainly my personal experience: my haphazard, process-free way of hacking delivers solid results very fast.

Re: TDD did not live up to expectations

#182
post #119
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.

You are correct. Not only this, but it's a blatant violation of TDD. TDD is having a single test go red->green, not a suite.

Exactly this. It's Red, Green, Refactor.

1. Write test; build fails because code under test DOESN'T EXIST

2. Write the least amount of code needed for the test to pass

3. Refactor & repeat process ad infinitum

The Wikipedia entry for TDD also states this explicitly [0]

  This is a differentiating feature of test-driven development versus writing unit
  tests after the code is written: it makes the developer focus on the requirements
  before writing the code, a subtle but important difference.
[0] https://en.wikipedia.org/wiki/Test-driven_development#Test-d...

Re: TDD did not live up to expectations

#183
post #58

Earlier quoted context omitted.

I think TDD works great if you have a very clearly designed input or interface. A programming language falls under this category: here's a piece of code, make sure it compiles and returns the correct output is a perfect test. And one which you can defined beforehand and is achievable to write as a test. However, programmers are often not in such a luxurious position. Business requirements are unclear, it is unclear w…

It's exactly the opposite. TDD was a put forward as a solution to unclear, changing business requirements. It allows you to adjust course very quickly when the business realizes its requirements were off and new set of requirements are needed. Robert Martin has even mentioned that it's a waste of time if you have a full 100% specification available to you, or when you already know what the final solution is and simpl…

I'm not an expert on TDD, but how does TDD help in this situation?

If your requirements change, your existing tests and code become (partly) useless. This would indicate the most efficient way is the exact opposite where you test minimally until the requirements have stabilized.

Re: TDD did not live up to expectations

#184
post #64

Earlier quoted context omitted.

No. TDD failed for engineering reasons in addition to economic ones. The main failing of TDD is the assumption that you know all of the tests that you will need before you know your software. This is true in bridge building as much as it is in anything else. Until you fully know the domain of what you are building, you cannot possibly know all of the things you need to test for. To that end, if TDD were focused aroun…

Yes, precisely. TDD works for experienced developers who know the problem domain well. It does NOT work for that new junior dev you hired straight out of college. They need to write functions and features first and see the spectacular ways in which those functions and features can fail (in a dev/test environment, hopefully), and then use that experience to switch over to TDD when they write a similar feature/function…

[deleted]

Re: TDD did not live up to expectations

#185
post #85

Earlier quoted context omitted.

People have a constrained view. They see their own problems and have seen the "old" way do nothing but fail and the "new" way do nothing but succeed. What other reaction would you expect? If they actively researched and looked beyond their personal experience then dramatic 0% to 100% Success rates would turn into more reasonable assessments. I think my view on TDD is more reasonable than most of the zealots, but I st…

" have seen the "old" way do nothing but fail and the "new" way do nothing but succeed." When I look at TDD I see a lot of success but also a lot of fail once people start pushing it too far. To me a fail is when the mock becomes more complex than the real system or a system can't be refactored because the refactoring of the tests takes too long or the tests are just so complex nobody wants to touch them. This remind…

I think you are totally correct both in your view that some take goods things too far and that this isn't the first time this pattern has been repeated.

I wonder what things I am expounding now that I will pull back on in the future?

Re: TDD did not live up to expectations

#187
I've seen TDD used once really well in a university setting where it was used only for shared libraries/services that could be used by multiple other teams or departments but not on individual (front facing) projects.

Probably because only the best developers on the team worked on the shared services it eliminated the refactoring issue as well as ensuring shared services could be a lot more reliably and safely updated.

Re: TDD did not live up to expectations

#188
post #8

In the earlier days of the ruby community, I feel TDD was seen as gospel. And if you dared say that TDD wasn't the way (which I always felt), you'd feel like you were ostracized (update: just rewording to say, you'd worry that it would hurt you in a job search, not that people were mean to you). So I never spoke up. I feel like I was in the TDD-bad closet. I absolutely think _tests_ are useful, but have never found a…

Anecdotally, the cleanest, most maintainable code I have ever seen at work was the result of a TDD-mandatory project.

Equally anecdotally, that was the most efficient project management I have ever seen at my workplace.

Economically, our branch office was shuttered, and all employees laid off, just a few months after we delivered it, for almost entirely unrelated reasons. As it turns out, the only reason we did the TDD project at all is because our primary contract had not been renewed, and it was a lower-value contract. After it was done, we didn't have enough work left to do. But more importantly, the main office didn't have enough work to do, so they slurped up our dregs, kicked us to the curb, and sold themselves to a bigger company.

Perhaps the lead dev saw the writing on the wall, and wanted to make a showpiece to boost everyone's resumes. Perhaps he foresaw that one of the several companies we might end up with after the diaspora might get maintenance responsibilities, and that person shouldn't hate their former team for writing crappy, unmaintainable code. Doesn't matter. Did it once, and it turned out great.

I still get nostalgic for it sometimes, when I am working in the sloppy mess I am currently assigned to.

Re: TDD did not live up to expectations

#189
post #172

When you look at the TDD evangelists, all of them share something: they are all very good – probably even great – at design and refactoring. They see issues in existing code and they know how to transform the code so it doesn’t have those issues, and specifically, they know how to separate concerns and reduce coupling. I think one of the selling points of TDD, and something I hoped for from TDD, was that causation we…

> I've also seen people mangle well-factored but untestable code in the process of writing tests, which can be a tragedy when dealing with a legacy codebase that was written with insufficient testing but is otherwise well-designed.

Have you read Michael Feathers' Working Effectively with Legacy Code? [0]

In his definition of legacy code it is any such code that has no test coverage. It's a black box. There are errors in it somewhere. It works for some inputs. However you cannot quantify either of those things just by "inhabiting the mind of the original developers." The only way to work effectively with that code base in order to extend it, maintain it, or modify it is to bring it under test.

This is far more difficult than it sounds with legacy code than with greenfield TDD for the aforementioned reasons: there are unquantified errors and underspecified behaviours. You can't possibly do it in one sweeping effort and so the strategy is to accept that tests are useful and to add them with each change, first, before making that change and using the test to prove the change is correct.

Slowly, over time, your legacy code base surfaces little islands of well tested code.

You have to be deliberate and careful. You have to think about what you're doing.

This is a much different experience than writing greenfield code. TDD is effortless and drives you towards the answer in this case.

[0] https://www.amazon.com/Working-Effectively-Legacy-Michael-Fe...

Re: TDD did not live up to expectations

#190
post #179

Earlier quoted context omitted.

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.…

It’s funny that you say “I'm designing it in response to real client code.“ To me, a test is not real client code. Real client code is code that calls the API in service of the user. E.g. the real client code for the Twitter API is in your preferred Twitter client, not in the tests that run against the Twitter API.

That's the caveat I mention in my second paragraph.

But yes, if the tests are well-designed and built with actual real-world experience, I do treat them like real client code. Someone looking to use the library should be able to read the unit tests and have a pretty good idea what code they need to write and what pitfalls they'll encounter. And when the library is redesigned or refactored, the tests are first-class citizens; they aren't mindlessly updated to fit the new code, they're considered alongside other client code as something that may or may not have to change but ideally wouldn't.

Post reply on HN