Things I learnt by not writing tests
rfw.posterous.com
rfw.posterous.com
I learned exactly the same lessons from writing code in a functional style. The experience changed my style for the better, and that carries over even when I'm using a language that doesn't lend itself very well to functional programming.
Most of the features I develop aren't good ideas in the end. Writing a test for a feature that you are going to dump after testing it with actual users is a waste of time.
Once a feature has proven its worth, I write tests to protect its value.
"...shaking things up, doing things a different way for awhile..., is never a bad idea."
I recently spent some time forcing a friend of mine to learn some basic Scheme (which I learned in school, and have always loved), to try his hand at programming. This led to basically reading though my Scheme book again and hacking through some examples. Going back to work - developing in Java - I found myself writing much more concise code and spending enough time thinking about the problem to find a solution that felt elegant.
Edit: I'd add to the article's point by saying: don't stay in the same environment for too long, or you'll get stale. Switch things up from time to time, even if that means switching to an environment that is inferior in some ways - you'll get something out of it.
I agree with the original poster -- it's important to slow down and think about the problem. Then again, I'm a big fan of trying hard not to write code you already understand too well -- that means that you're repeating yourself :-)
Prolog is far from perfect (its default search mechanism gets stuck in left-recursive clauses), but it's a start, and computers have gotten considerably faster since the 70s...
AFAIK, the best known success of declarative programming is writing a pattern matching specification (with ML, Prolog, Erlang, Haskell, or various Lisp macros) and compiling it to the necessary nested if / switch statements, rather than generating it by hand. I guess it overlaps with parser generators, and some other DSLs, too.
After over a decade of writing software, I'm willing to accept this up-front cost in favor of long-term (and often short-term) gain. Sure, I can quickly hack out code when I'm not writing tests, but long term experience with both methodologies has demonstrated to me that it's not worth it.
Like many other 'methodologies', it has uncritical advocacy. (http://blog.objectmentor.com/articles/2009/10/07/tdd-derange...) (HN discussion: http://news.ycombinator.com/item?id=866707)
I agree that automatic testing is nearly always a net gain, but using tests themselves as the primary driver for the design process suggests to me that the developer has little other design experience to draw upon.
Secondly, I've realised that when I don't write tests I code too fast. TDD acts as a constraint on myself, something which stops me from running ahead of myself and forces me to stick around a particular problem area for long enough to understand it better, and often learn something that otherwise I'd have missed.
I don't remember ever reading a blog claiming that would be an advantage of TDD before I started.
Extreme Programming was cognizant of this effect quite a while ago. (Actually all of the parts of XP were supposed to have beneficial side effects that reinforced the other parts.)
A good portion of interconnected web apps are API calls, and database updates/queries. For the type of programming I'm learning/doing now (web programming in ruby on rails), the tests are never sufficient to test anything. I fire up a browser and get a user eye view of what's happening while looking at the log. Maybe that's old school thinking but it's working well for us as this point.
Would appreciate any tips to help us be more efficient of course (victusmedia.com)
What I really wanted to know was "will my site work," and I found Cucumber+Webrat to be an efficient way of being sure of that. I TDD Cucumber scenarios now, and it makes me more confident without feeling like I'm spending all my time fighting with a testing framework.
One thing that always frustrates me in these debates is all the hypothesizing people who are skeptical of TDD do about what it would mean if they were to use it. For example:
"For the type of programming I'm learning/doing now (web programming in ruby on rails), the tests are never sufficient to test anything."
RoR is specifically built to make test-driven web development easy. I'm not saying the poster is wrong not to use TDD on their project, just that statements like that should not be taken at face value. It is clear that at least for some people doing certain types of work TDD is a big help. That's an indisputable fact. Therefore, the only reasonable positions one might hold are the following:
1) I agree with these people. TDD is great and I use it all the time. 2) I don't want to use TDD. It just does not match the way I think about my work. I choose not to use it, but I do not claim to know why using it is a bad idea. 3) I tried TDD and mastered it. Anyone well-versed in TDD would confirm that I can do it "the right way". I found the following problems in my test-driven code: ... For those reasons I would recommend that people stay away.
I think any other position would be disingenuous or lazy. Also note that only opinion 3 is in any way interesting to read about. It kind of feels like unless you're making that claim there is no useful way to comment on the utility of TDD.
So let's say I have this new way of doing things. It's called "hit your head with a hammer". I'm crazy about it and wrote a bunch of books about it. Other people have tried hitting their head with a hammer and, although there are many detractors, there are also some big fans.
So what you're saying is: we cannot make a legitimate (or "interesting") observation about "hit yourself in the head with a hammer" unless we also have mastered the art of doing it. Only then would we have something worthwhile to add.
I'm not saying TDD is bad. What I'm saying is that it's perfectly fine to look at the phenomenon from the outside and make general observations about it. For instance, "TDD is very hard to impose on most teams" or "When implementing TDD for the first time, teams experience a significant drop in performance"
I'm sure there are lots of others.
Uncle Bob (and others) have made a mockery out of informed discussion in regards to TDD. Here's hoping we can keep a reasoned and civilized discussion going in the community.
[Edit] I also was not trying to suggest a general strategy for evaluating programming practices. I made the assertion it was clear TDD has value at least in certain contexts. In the case of TDD I think it is evident its benefits are subtle enough to approach the issue more carefully.
With that said, you seem to be missing an option:
4. I have evaluated TDD, and I see its value in many cases. But I also see cases where it is not appropriate or at least suboptimal. I therefore consider on a project by project basis whether I should use it.
My experience in TDD is nowhere near enough to be comfortable making statement 4 myself, but I have heard it made and I think even most people that disagree with it would see it as a reasonable position to hold.
In defence of the article, tdd is something i do in my head but rarely to the nth degree in practice. I'm more of a fdd kind of person, but I think that there are a lot of parallels with the two approaches.
I don't think a lot of people would argue that writing tests can be a good way to get feedback about a design. Some particularly vocal TDD advocates seem to be making it into an all-or-nothing issue, though.