Live data from Hacker News

Why TDD isn't crap

hillelwayne.com

51–60 of 171 posts

Re: Why TDD isn't crap

#51

You know what's awesome about TDD? It means I, a nobody, can contribute to a huge open source project with lots of moving pieces and be pretty confident that I'm not catastrophically breaking anything and that my feature works as intended. That's awesome!

Right. Good tests are a passive communication tool. They communicate expectations. Most of the discussion here revolves around different people having different expectations. I think the "please test" people have a better argument mostly because they're advocating for tools for good communication.

Re: Why TDD isn't crap

#52
I haven't shared this on HN but I saw this on another forum and thought this was a really fantastic example of what you can end up with, in the real world, when you are driven by tests. Real-world example:

https://i.redd.it/lwin56fisdsz.png

It doesn't look like a joke to me. It only works over integers so the code is absolutely correct.

It also strikes me as the kind of convoluted logic that someone took a really, really long time to come up with, before it finally worked. (As indicated in the comment.)

A test can hardly capture what's wrong with this code. But any human can see it instantly. (And it's kind of weird that the programmer didn't.) I think most people can think of braindead decisions that are not really captured by testing.

Re: Why TDD isn't crap

#53

You know what's awesome about TDD? It means I, a nobody, can contribute to a huge open source project with lots of moving pieces and be pretty confident that I'm not catastrophically breaking anything and that my feature works as intended. That's awesome!

That seems to do more with automated testing (unit, regression, integration, etc) than with TDD. It's important not to conflate the two because TDD proponents say that TDD is not primarily about testing.

Re: Why TDD isn't crap

#54

I expect the reason TDD is so controversial on here is people can't see the long term benefits of tests, and instead only think in the short term. But in the commercial world, code you write can potentially have a lifespan of 30+ years. In this case, making a choice to write tests is the difference between writing a maintainable component in the future vs writing a soul-destroying 'legacy system'. If you agree tests…

There are undoubtedly multiple reasons. One reason is that there are domains where the hard problems are integration problems. If the point of your program is to poke/sample some physical object, talk to another opaque chassis/address space, execute realtime tasks (which in practice often includes UI/UX concerns), etc., then extensive integration testing is absolutely vital. If you focus on some other testing discipline and try to de-emphasize integration, there is a considerable risk of fooling yourself about whether your program actually does what it says on the tin.

Re: Why TDD isn't crap

#55
The only thing I disagree with in this article is the leeway given to supposedly legendary programmers who can somehow write bug-free code without tests, specifications, or an inkling of communication with others.

First, it's probably not true. Linus Torvalds is not a legendary human being who can write critical systems without a single flaw. He relies on legions of human beings to carefully check and review every line of code before he even looks at it. There are discussions on mailing lists. There are arguments and disagreements. There's a process there. He doesn't just flit his fingers across the keyboard and output amazing, error free code. It probably has tonnes of errors.

Linus' philosophy is that errors aren't the end of the world and someone will patch them when they are uncovered.

For some use cases that's fine. However there are plenty of applications where a more proactive approach to correctness is necessary: real-time systems, safety critical systems, and yes... even security.

Maybe TDD is a misnomer. I think we should call it specification driven development. Unit tests and integration tests are just a weak form of specification. They provide theorems in the form of examples that we try to prove with an implementation. Property based tests give us more examples to quantify assertions over. Model checking can test liveness as well as safety in our high-level designs... how much you need to specify and how thoroughly really should be a factor of the risk and complexity present in the requirements of the system.

To use an analogy: blueprints. If you're just building a shed or a small footpath then it's enough to sketch your idea on a napkin. If you're building a house you need to have a more specific and detailed plan that passes by a civil engineer. And if you're building a sky scraper then you need to be thorough and able to convince others of the validity of your designs.

(credit for the analogy should go to Leslie Lamport).

I think most software projects are at the house level in terms of risk. You could get by with using a dynamic language and a few unit tests if you value productivity more than correctness. That just means you're willing to accept that you will have higher reported error rates and are comfortable with potentially losing customer data or a higher risk for security vulnerabilities. You can lower your risk if the project requires more sensitivity to data consistency or security by using a sound type system and encoding your assertions at the type level, add some property-based tests, and more integration and unit tests. It's a spectrum one should consider.

I know we all like to write code and sometimes we even hear ourselves saying, "Well if you wrote the perfect specification you might as well have written the software," but don't be fooled.

"Software engineering is the part of computer science which is too difficult for the computer scientist." -- Friedrich Bauer

Re: Why TDD isn't crap

#56
post #45
post #28

The problem with many TDD critiques is that they offer no alternative. The original presentation: https://www.youtube.com/watch?v=DQBf6li1hww is a case in point. Presenter takes what he believes to be TDD's four main points, some of them strawmen, and mocks them. He does make some good points, but here's the problem: he offers no alternative. If you're not writing tests as you go, that you run before every commit (or…

You're right, I also don't know good alternatives. I wrote my first big API with many tests, hundreds of them. Then the requirements changed and all of them failed. People worked for weeks to get the tests passing again. So just writing many tests up front in a new project doesn't seem to help anyone. Also, I went from feature to bugfix sprints. First I implemented some features, then they got tested by non-devs, the…

In most statically typed languages, the bugfixing (usually) takes longer because you need to do many more things each time you refactor. An enterprise Java application doesn't typically pass around the equivalent of a JS object. It passes around Users, Admins, and Guests. But then some features in Admins need to be added to Users without affecting Guests. But Guests inherit from Users, so you have to go back and restructure the type hierarchy. But it turns out that User is a Hibernate entity, so you have to make sure you don't change your DB schema on accident.

Using a static language does help with some bugs (where it effectively serves as a compile-time test suite), but it can also increase coupling a lot. It's not easy to quantify that tradeoff in abstract. I'd be wary of people overselling aggressive compiler checks leading to productivity boosts.

Re: Why TDD isn't crap

#57
post #35

Earlier quoted context omitted.

"having test play some part in how the code takes shape" That is exactly the point why I don't like TDD. I mean, there are enough constraints that shape the code, why should something artificial like tests shape it too? With mocking and everything you end up writing code for tests and not code for your problems.

Well, you write code for design flexibility. Testing just forces the issue and helps you explore possible design needs. For example, what if the database query you're using isn't suitable any more? Instead of designing around a User table, you start passing around User records. Then your design is more future proof in case you start getting Users from a service or in-memory cache instead of a database. > ...not code…

This is exactly the problem. In general you should not be writing code for design flexibility. Your code should contain the minimum number of abstractions to satisfy its requirements. If flexibility is a requirement right now then that's ok. Otherwise refactor in the flexibility later. But don't make the code flexible for the sake of tests. It vastly over-complicates it for no benefit. Instead write tests as close to the requirements level as possible (ideally most of your tests should be just below the ui)

Re: Why TDD isn't crap

#58
post #8

Like the author, I subscribe to the less strict view that TDD isn't necessarily about writing the test first, but rather about having test play some part in how the code takes shape. Unlike the author, I absolutely believe that tests are about design. More specifically, they're about identifying coupling so that you can reduce it. The function being "awkward" to use is part of it, but code which is hard to test is al…

I've always thought that the bulk of the value of tests is for the unfortunate person who has to refactor or extend your code years down the track. By that logic, if you write testable, but untested code, then you're still making it difficult for people to refactor later. This applies even if the code is well designed and uncoupled.

You don't even have to think that far ahead - consider some code you wrote in week 1, that was then modified by a colleague in week 2, now you return to the code in week 3 - what does the code do? Any mental model you had at week 1 is now irrelevant as the code has changed in unknown ways. What is the current intent of the code? Do you feel safe modifying it, despite the fact you no longer know how to manually test all the end points? You only have to miss one to have clients and managers breathing down your neck when the blame game is played as to who broke the app in production.

Re: Why TDD isn't crap

#59
This is a very poorly researched article, and the previous was as well.

With people like Capers Jones and others doing piles of studies 30+ years ago, I'm confused why someone says there are no studies on TDD.

My bet is the author doesn't have access to the relevant historical papers, and doesn't know they exist.

Re: Why TDD isn't crap

#60
post #35
post #8

Like the author, I subscribe to the less strict view that TDD isn't necessarily about writing the test first, but rather about having test play some part in how the code takes shape. Unlike the author, I absolutely believe that tests are about design. More specifically, they're about identifying coupling so that you can reduce it. The function being "awkward" to use is part of it, but code which is hard to test is al…

"having test play some part in how the code takes shape" That is exactly the point why I don't like TDD. I mean, there are enough constraints that shape the code, why should something artificial like tests shape it too? With mocking and everything you end up writing code for tests and not code for your problems.

Tests are not artificial constraints. They are the guarantees which (should) matter most to your users and stakeholders.
Post reply on HN