Live data from Hacker News

Giving up on test-first development

iansommerville.com

111–120 of 224 posts

Re: Giving up on test-first development

#112
post #27

Earlier quoted context omitted.

> that tells us that we wrote a bad test, not that TDD is bad I strongly disagree. The only thing that matters to how software works for an end user is its boundary. You simply can't do TDD by only testing the boundary. You have to write a test before each unit of code, so you have to test those internal interfaces, the way units of code work. But that is exactly the stuff that should be allowed to change. It's a mis…

> The only thing that matters to how software works for an end user is its boundary. You're ignoring the fact that tests aren't only to validate "end user functionality". They're also there to make life easier for the developer; to make both initial development and maintenance easier. If I need a custom sort algorithm for my product, I'm going to write unit tests for it's implementation. I'm also going write function…

> If I need a custom sort algorithm for my product, I'm going to write unit tests for it's implementation.

I would start with writing an assertion about the end state of the sort. Then using syntactic substitution of the predicate calculi derive the program by assertions.

I'd then have a specification of the algorithm as a mathematical model from which I can check every possible execution for the entire domain on the sort. If I'm so inclined I would have a good basis for a proof.

The unit tests then become assertions on the implementation and don't have to verify correctness.

It would be awesome though if I could just generate the code directly from the specification!

Re: Giving up on test-first development

#113

Earlier quoted context omitted.

Yeah, I mostly prefer end-to-end tests as well. Though to be fair, they are often slower than unit tests, because you need to start up the whole system. And they are worse at pinpointing problems, though that doesn't seem to be a big deal in practice.

I in part agree with the pinpointing, though in my experience this really boils down to an issue of scope and how much of the data you want to test in each of your tests. E.g. an API returning user data, do you have one test for the whole set of data or one test per field. For our use case we have some pretty "fancy" deep-equals logic for nested structures and allow to specific fields as "to be ignored" in our test e…

Count yourself lucky that your test takes 10 seconds. A partial build on my project takes ~3 minutes to compile + link. A full build is about 3 hours for everything.

Re: Giving up on test-first development

#114
post #6

Like all things in life TDD should be taken in moderation. It's an excellent process to create stable and maintainable code, but it does not fit every bill. But abandoning it completely on the grounds that it sometimes makes you write "bad software" is a bit weird to me, in fact, one of the main arguments for TDD is that it makes you write better code. I found that it does make you write better code many times. So li…

> Like all things in life TDD should be taken in moderation.

You're points are all good, but your opening one especially.

The obsession that some developers have with methodological purity can be really puzzling sometimes.

Where I'm at: I work in research and engineering (in the gov't, on the borderline between industry and academia), and I can say that doing any sort of testing at all (either up front or later on) is an improvement over the untested, undocumented, unversion-controlled status quo that exists in a lot of cases.

Re: Giving up on test-first development

#115
post #6

Like all things in life TDD should be taken in moderation. It's an excellent process to create stable and maintainable code, but it does not fit every bill. But abandoning it completely on the grounds that it sometimes makes you write "bad software" is a bit weird to me, in fact, one of the main arguments for TDD is that it makes you write better code. I found that it does make you write better code many times. So li…

I don't understand why people tend to turn useful things into strict ideologies.

TDD is super useful for simple algorithms. It gets harder once you get into more complex scenarios like multiple components working together. If TDD is not useful for some cases then don't use it there and use it where applicable. Or think about how you can make it work. It's not that hard.

Re: Giving up on test-first development

#116
post #11
post #5

From the article: Because you want to ensure that you always pass the majority of tests, you tend to think about this when you change and extend the program. You therefore are more reluctant to make large-scale changes that will lead to the failure of lots of tests. Psychologically, you become conservative to avoid breaking lots of tests. Interesting. I've often found that the lack of tests leaves me absolutely terri…

It's not a good argument against testing, I agree. Automated testing is a huge boon for software quality (though by no means a panacea). But TDD, in my experience, gives a slightly different dynamic. Because you generated the code being motivated by the tests, there are a lot of unit tests that don't test functional units - tests that are essentially testing implementation decisions. I've seen situations where that b…

"I've seen situations where that big refactoring would involve scrapping or rewriting tests, and that causes its own kind of architectural conservatism."

Yes, rewriting tests is part of a refactor. You always have to be willing to do that or just scrapping outdated tests.

Re: Giving up on test-first development

#117
TDD:

Write the test case representing "this USB host controller driver has no race conditions", and then just fill in the code, and out pops a race-free USB host controller driver!

(Of course, it does nothing so far other than demonstrating freedom from races, but that's just a small matter of writing more tests for actual USB requirements and fulfilling those.)

Re: Giving up on test-first development

#118

TDD: Write the test case representing "this USB host controller driver has no race conditions", and then just fill in the code, and out pops a race-free USB host controller driver! (Of course, it does nothing so far other than demonstrating freedom from races, but that's just a small matter of writing more tests for actual USB requirements and fulfilling those.)

It doesn't even demonstrate freedom from races.

TDD is a valid software development methodology for certain use cases (mainly sequential algorithms, e.g., financial calculations), but not for concurrency control.

Re: Giving up on test-first development

#119

Earlier quoted context omitted.

To be fair the author was abandoning TDD not tests. He explictly said that he'll add tests after he writes the code.

Perhaps the author is more disciplined than me, but I'd have an extremely hard time actually following through and writing tests after-the-fact. After the code is "done", it's hard to keep working on it—no matter how much the "extra" work is needed. I find tests to be extremely helpful for designing APIs. I write tests to enforce the contract my API is making with its consumers. Therefore, TDD forces me to consider t…

This is a great way to create APIs that are hard or nearly impossible to implement properly or efficiently. I can imagine how this could easily lead to horrible API design like a well-known stdlib `gets` function. From the user perspective, gets is a perfectly fine function. Unfortunately there is no way you could write a safe implementation, because in C you have no way of checking arbitrary buffer size. Low level implementation details do affect how we design APIs.

Re: Giving up on test-first development

#120
post #40
post #14

Earlier quoted context omitted.

If you don't know what the code is supposed to do, how are you writing it?

The preference function (or oracle) can return a truth value without you necessarily having insight into its inner workings. People "know it when they see it" without necessarily being able to define it. So you write the code; expose it to a preference function / oracle, iterate, and hill-climb towards a local optimum. The revealed preferences may give enough information to make a creative leap off the local hill ont…

> The preference function (or oracle) can return a truth value without you necessarily having insight into its inner workings.

Is this preference function implemented on a computer, or is it just a person giving you seemingly random answers in response to whatever you tell them?

> People "know it when they see it" without necessarily being able to define it.

That path leads to hell.

> After a solution has been found, then you can write tests.

what exactly would you test? Tests make sense when you want to check that your implementation conforms to a certain set of logical rules, but where exactly is the logic in the process you outlined?

Post reply on HN