Live data from Hacker News

Giving up on test-first development

iansommerville.com

61–70 of 224 posts

Re: Giving up on test-first development

#61
post #14

TDD is nuts for code without a client or specification. The whole point of tests is to ensure that the code does what it's supposed to do. When you have neither client nor spec, how are you supposed to know what the code is supposed to do ? There is, IME, a >90% chance that any such code will be ripped out and replaced as you develop a better understanding of the problem domain. I've found it's pretty useful to go ba…

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

I'd translate this as "don't use tests for proof-of-concept code". At least not when success is easily observable.

Re: Giving up on test-first development

#62
post #27

Earlier quoted context omitted.

> Because you generated the code being motivated by the tests, there are a lot of unit tests that dot test functional units - tests that are essentially testing implementation decisions. I've seen this happen to myself numerous times as well, but I don't think this is good argument against TDD. If a tests fails because the implementation details change, that tells us that we wrote a bad test, not that TDD is bad. As…

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

Not this TDD folk. :-)

Re: Giving up on test-first development

#63
Most people probably felt the same way after only a "few months" (best-case, perhaps less) of practicing TDD.

And certainly TDD is harder as you approach the GUI, you want to test in vague ways which don't break with every change. If you thoroughly test all of the underlying behavior, implementing a GUI is typically incredibly trivial because everything beneath it is known (and proven) to work. Most of the article is not related to the GUI.

> ...it doesn’t work very well for a major class of program problems – those caused by unexpected data.

This is a hollow argument. Regardless of development methodology, if unexpected data isn't considered at all it could have all kinds of side effects.

Regarding conservatism with breaking tests (many tests failing for one change), it's likely the result of a structural problem within the application if it's an intimidating number of failures.

> It is easier to test some program designs than others. Sometimes, the best design is one that’s hard to test so you are more reluctant to take this approach because you know that you’ll spend a lot more time designing and writing tests (which I, for one, quite a boring thing to do)

Not sure how this applies to TDD, if you're writing tests first you aren't deeply concerned with designing tests because you're imagining what the interface for well-designed code would be, and then you write it. It frequently sounds like the author jumps into writing tests without any forethought.

> In my experience, lots of program failures arise because the data being processed is not what’s expected by the programmer. It’s really hard to write ‘bad data’ tests that accurately reflect the real bad data you will have to process because you have to be a domain expert to understand the data.

If you don't understand the variety of inputs, how can you possibly validate them? Programmers should have some domain understanding, certainly program inputs fall within that realm.

> Think-first rather than test-first is the way to go.

I agree; but step 2 should be testing in my opinion. Test first is just the first tangible work product, it isn't a ban on thinking.

Re: Giving up on test-first development

#64

I recall a situation where a manager was pushing for TFD in an Agile environment. What a nightmare, the two just don't mix. The biggest issue isn't the approach itself, but when it hits Buzzword level with the managers who have no idea how development really works.

This is true. These kinds of changes should come from the professionals -- it is, after all, their reputation on the line. As a software developer and executive simultaneously, I walk a fine line -- usually I adopt a practice myself and show people what it has done for me and the maintainability of my code. Then if people are curious I help. If not, that's fine. They'll come around or go somewhere else where engineering is less rigorous.

It's extremely tricky to avoid being threatening as a leader. Your position gives you power nobody else believes you deserve. Even when, sometimes, you do. Not saying I deserve it, but there are those that I've worked with that did, and I only noticed in hindsight. F'ing limbic system.

Re: Giving up on test-first development

#65
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…

One good way to the limit breakage in such cases is to solely perform black box tests on the API level. In case of our Node.js based Backends we don't ever write a single classical unit test, instead we have a custom Framework built on top of Mocha which performs tests on the HTTP layer against all of our endpoints. This works remarkable well in practice and allows for large scale refactorings under the hood with lit…

I'd say do both. Unit tests often help me to make my code more readable/decoupled and also help to spot potential problems early on. They also act as a kind of abstract documentation for how things are supposed to behave/work. But functional/integration tests are what matters most in terms of being confident of deploying big changes because you can ensure that all the endpoints that are actually consumed by clients work as they should, but it doesn't help too much with spotting problems on the code level.

Re: Giving up on test-first development

#66
post #17
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…

From what I understand author is not questioning the usefulness of testing, just TDD approach of writing tests first. I personally prefer a sandwich approach, I start with code first, and then write tests for it as soon as I have that little piece of logic finished (usually a method or two). Then I add more code, followed by more test, and so on. Works great for me and my team.

I agree. If people started viewing coding as an art instead of a strict science I think people would feel more comfortable doing something like this instead of a strict Test First or Test After.

Re: Giving up on test-first development

#67
post #27

Earlier quoted context omitted.

> Because you generated the code being motivated by the tests, there are a lot of unit tests that dot test functional units - tests that are essentially testing implementation decisions. I've seen this happen to myself numerous times as well, but I don't think this is good argument against TDD. If a tests fails because the implementation details change, that tells us that we wrote a bad test, not that TDD is bad. As…

> 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 functional tests to make sure the end user is seeing things sorted. However, those tests serve different purposes.

The unit tests allow me to write clean, simple tests that show exactly what the implementation is supposed to be doing for different inputs. That allows me to change the implementation of the sorting algorithm later and worry less about breaking the functionality.

The functional tests are (generally) not going to be as clean and obvious, nor cover every possible partition of inputs that the implementation could get.

Re: Giving up on test-first development

#68
From the article:

I deliberately decided to experiment with test-first development a few months ago.

and

the programs I am writing are my own personal projects

If you have no real experience with TDD and you're hacking away at personal projects, I can see where you might not find TDD to be useful.

If you're experienced with it and working on a project that is going to be sizable and for use by others who might be paying to use it, TDD is indispensable.

I've seen a lot of fads come and go over the years. I've tried many of them out just to see how they fit my style of working. TDD is one of those paradigms that has withstood the test of time.

Much more important than code coverage and ability to make changes without breaking things as mentioned in the article, TDD forces you to think about your software components from the client perspective first. It's that discipline that I appreciate more than anything.

Re: Giving up on test-first development

#69

TDD is nuts for code without a client or specification. The whole point of tests is to ensure that the code does what it's supposed to do. When you have neither client nor spec, how are you supposed to know what the code is supposed to do ? There is, IME, a >90% chance that any such code will be ripped out and replaced as you develop a better understanding of the problem domain. I've found it's pretty useful to go ba…

how are you supposed to know what the code is supposed to do?

That's the beauty of TDD. It forces you to sit and work out, "What is this code supposed to do from the client perspective?"

It battles the all-too-prevalent developer inclination to just start running with implementation without even taking the time to understand what problem is being solved.

Re: Giving up on test-first development

#70
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…

I think the language and in particular the type system matters a lot. So making big changes in the absence of tests in a Swift or even the somewhat more loosely typed Objective C is less scary than in Ruby and Javascript application.
Post reply on HN