> This is also why TDD is a failure and complete bullshit in how it is advertised. Tests don't save you from doing stupid shit.
Why do people think tests are for that? Tests are basically same as free climbers safety lines. They won't protect you from everything and sure they are tedious to place, but once they save your tush, you'll be glad they were there, and you weren't splattered across the floor.
I've seen lack of tests in practice and it's not pretty. Nope. Not pretty at all. Basically lots of entangled undocumented, untested systems that you can't refactor because your refactor just broke some code somewhere.
To demonstrate some of the bugs, if you accidentally type your username wrong, the whole server crashes and resets. It was not pretty.
> Tests are basically same as free climbers safety lines.
I never claimed that they aren't useful.
> once they save your tush, you'll be glad they were there
Of course, I'm glad when I work on well tested codebases. But I was speaking about the advertisement that it received. And people really do think that because that's what TDD enthusiasts claimed - and note that I'm making a difference between testing and TDD.
The introduction is genius and I quote: "Ron Jeffries attempts to create a sudoku solver - here, here, here, here and here. (You really ought to read these articles. They are ummm...{cough} ...err.... enlightening.) ... Peter Norvig creates a Sudoku Solver."
I don't honestly know what people claim TDD does. But where the requirements are clearly specified (albeit changing) and problem space isn't well understood it has its uses.
The example given is one TDD is kinda one of worst case scenarios for it. If for example the goal was to write a novel game that is popular with some audience Norvigs analytical approach would falter. TDD wouldn't fare much better but I believe it would be better than purely analytical problem. I however have little doubts Norvig would adapt to the challenge.
Do note that by TDD I consider only red-green-refactor methodology on clearly specified parts and adding tests on encountered bugs. Rest I consider fluff.
Summary: Tests and test first design is a tool. It can't be used for everything.
> Tests are basically same as free climbers safety lines.
Absolutely. So many people seem to aggressively argue for 'test all the things!' or 'test nothing!', where I imagine most jobbing programmers are practical enough to test the key things first and then expand from there. If I'm greenfielding something, I'll do TDD-first, but on new features on an old code-base or legacy apps it's initially way more just a catch in case I come off the mountain unexpectedly. I don't want to spend a day writing a feature and then find out I've broken something fundamental, I want to find that out after a couple of hours.
"you can't refactor because your refactor just broke some code somewhere" - picking a language that is not matched with first-class automated refactoring (ReSharper, IDEA) was their first mistake (rather than lack of unit testing).
You couldn't rename things because they used AspectJ to bind certain method names to some validation methods. Of course this was well documented on a dark side of planet orbiting Andromeda.
Also the Javascript used #id an suffixes to call JSP fragments. You change the name of the div in that JSP fragment and you have to change any mention of it in any JS or Java files.
On the other hand an expressive static type system (with emphasis on expressive, because Java's type system doesn't qualify) can save you from countless of accidental bugs happening - and a single bug that's caught by the compiler is a bug that won't reach production.
Plus, static typing approaches the problem from a different perspective than unit testing. Through testing we try to prove that a piece of code conforms to the business logic that is being solved and to guard ourselves against regressions. A static type system on the other hand actually proves that your code has certain characteristics - for example depending on the language we are talking about, it can prove that you won't get any null pointer exceptions, or it can prove that the interface of this component is still the one expected by this other component, etc... for example I have a component modeled as a fairly complex FSM and I fixed a difficult non-deterministic bug by eliminating the possibility of it happening through the type-system - it was quite the eye opener.
Static typing doesn't negate the need for testing of course since they serve a different purpose, but if you find yourself writing tests for things that a compiler could prove, then you probably picked the wrong language.
You'd be surprised what transformation modern IDEs can do that IS refactoring, not just renaming and pushing variables around.
Plus, you're wrong: a lot of refactoring is also about renaming stuff and pushing variables around. You don't always have to rewrite everything in new hierarchies and patterns in order to do a refactor.
Renaming, pushing variables, changing their types, stuff like that. It's still
editing work. Can any IDE split the class into two according to methods'
responsibilities? Can it abstract a set of functions to a single generic
function? Can it get rid of unnecessary boilerplate code scattered around in
various classes? Can it change data structures used to store data?
Because refactoring is about making the code simpler and more flexible.
Rearranging that IDEs do is only a method (and not the only one) to achieve
that.
Anyone who doubts this should watch Jim Weirich's talk "Adventures in Functional Programming" - the last (and most mind-blowing) quarter of the talk is almost entirely made up of automatic refactoring.
Why do people think tests are for that? Tests are basically same as free climbers safety lines. They won't protect you from everything and sure they are tedious to place, but once they save your tush, you'll be glad they were there, and you weren't splattered across the floor.
I've seen lack of tests in practice and it's not pretty. Nope. Not pretty at all. Basically lots of entangled undocumented, untested systems that you can't refactor because your refactor just broke some code somewhere.
To demonstrate some of the bugs, if you accidentally type your username wrong, the whole server crashes and resets. It was not pretty.