Live data from Hacker News

Giving up on test-first development

iansommerville.com

41–50 of 224 posts

Re: Giving up on test-first development

#41
In my limited experience, tests should be written against a specification, not against code. Writing tests focused on code seems to often lead to tests that are too close to the implementation of the program, even with test-first approaches (you end up thinking about how you'll write the code when you're designing the tests).

By focusing on the specification, you can ensure that design decisions are made by the coder are fit for purpose.

I also think many tests would be better written as code contracts, you mainly want to ensure the inputs and outputs are valid, code contracts focus on this.

Re: Giving up on test-first development

#42

The author keeps talking about a "better design" achieved when not using TDD, and he goes on saying that sometimes a good design is a design that is hard to test. These are subjective, psychological feelings that, in my experience, bring only to maintenance nightmares and impossibility of doing any kind of refactor without the fear of breaking something. TDD might be difficult to do at times, but it has a very intere…

Testable design is often a poor design, mainly because of language limitations; abstraction and scoping for tests are not necessarily the best choice for abstraction and scoping for design.

Re: Giving up on test-first development

#43
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 nowadays do an approach where I don't write tests first, but I write down the test titles (I use a language where the testing framework gives a nice DSL to write nicely readable test names compared to method names) and I just mark them as pending (which will report as no test failures or passes but ignored cases). I rarely end up with the same test ideas and names which I started from, but since I only start with names which do not hinder refactorings this worked out surprisingly nicely for me.

Re: Giving up on test-first development

#44

As a suggestion, QuickCheck type testing frameworks are good for finding bugs relating to unexpected data. Summary of how they work: you say "this program takes a 32 bit signed int and a string" and the testing framework will throw it a heap of random ints and strings, some of which match the sorts of classic curve balls it might encounter (negative numbers, int max and min values, strings that are very long, empty s…

Any suggestions on any such frameworks for Ruby / Java?

Re: Giving up on test-first development

#45

TDD only works if the tests are written correctly. Tests are not about "code coverage", nor about establishing the exact sequence of things in stone. Tests are about fixing invariants. When a new project starts, I only know about 10-15% things for sure, and those are exactly which will go in tests, before writing any new code. I don't worry about some things in my code are not yet covered by tests; I don't know yet h…

> some crazy folks are even testing getters and setters — why?

Well, I can see the logic if your getters and setters are hiding more activity than simply retrieving/setting the value of a private field, which is the point of having separate getters/setters at all.

If you imagine a getFullName() / setFullName(name) pair, for example, that actually reads from/writes to two different private fields for first and last name (leaving aside middle names, internationalisation, etc), then there's some minimal logic there that you might want to test.

In a duck-typed language, when you're trying to ensure a class obeys an implicit interface, it may also have value.

Apart from that, for vanilla getters/setters, it's a little pointless.

Re: Giving up on test-first development

#46
post #11

Earlier quoted context omitted.

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…

> tests that are essentially testing implementation decisions. There shouldn't be any. Those are not useful at all.

See my reply above. I think your view is either naive, or you understand 'implementation decision' in too narrow a way.

Re: Giving up on test-first development

#47

Just like the chicken and egg, it doesnt matter which comes first, code or test. The key is that both are written, ideally around the same time and part of same changeset. Refactoring posthoc for testability is tricky and often brings to the surface poor software designs in the original implementation - bad coupling, module dependencies, leaky abstractions, etc.

I think there's something to be said for maybe saying test first. I tend to find writing tests second a little harder. If its a big complicated feature, its much harder to go back and try to think of all the test scenarios needed when its finished, there might be an edge case or a semi obscure case that may have been apparent at writing the code but gets missed when looking back and writing tests. But its preference.

Re: Giving up on test-first development

#48

As a suggestion, QuickCheck type testing frameworks are good for finding bugs relating to unexpected data. Summary of how they work: you say "this program takes a 32 bit signed int and a string" and the testing framework will throw it a heap of random ints and strings, some of which match the sorts of classic curve balls it might encounter (negative numbers, int max and min values, strings that are very long, empty s…

Any suggestions on any such frameworks for Ruby / Java?

There are a lot of external links for implementations here https://en.wikipedia.org/wiki/QuickCheck

Re: Giving up on test-first development

#49

Over the years I've gone from writing no tests at all, to being a die hard TDD purist, and then out the other side to writing some things with tests first, others with tests after writing the code, and some without any tests at all. In some situations I have clear view of what I need to build, and how that should work. TDD is great in that case - write a test for the expected behaviour, make it pass, refactor, rinse…

> you take the bad data that caused the bug, reduce it down to a test case

That's not really TDD anymore though - post-hoc testing of bad data is always going to be orders of magnitude easier because you have the bad data and you know what broke.

Re: Giving up on test-first development

#50
> I won’t spend ridiculous amounts of time writing tests when I can read the code and clearly understand what it does.

Is he arguing that simply trusting yourself not to make mistakes is a sufficient guarantor of quality? Ian Sommerville is the author of a famous textbook on software engineering, so it would be surprising if he was.

TDD is actually much more difficult in practice than people realise. I read Kent Beck's book and thought it sounded like utter horseshit. I tried doing it myself and decided it was definitely horseshit.

Then I came to work at Pivotal Labs. Now I am distrustful of code that was written before tests.

As for the argument that TDD distracts from the big picture, this is like saying that indicator signals and mirror checks distract from driving. Sure, when you are learning to drive, you feel so overwhelmed by attending to all the little details that you struggle to drive at all. You become unable to focus on your navigation.

After a while you learn the skill and it becomes automatic. TDD is such a skill.

Post reply on HN