in reply to Does anybody write tests first?
Yes. I try to work that way as often as I can. By writing the tests I get to play with the API before I commit to anything in code -- in essence, I refactor the API using the tests as a "prototype".
The other great thing is that it forces oneself to be specific as to what one expects often makes the coding job simpler.
Plus, I get to check that the tests actually *fail* when the code doesn't exist. When the code already is there and you write a test and it passes, how do you know your tests is actually doing what you think? Do you go back and break your code to confirm your tests -- if you're like most people, probably not. But by writing the test first, you get to see it both fail and then succeed, which increases the robustness of the test as well as the code.
Where I tend to make exceptions:
Some things are just really hard to write simple tests for (interactivity, complex dependencies on external programs or systems, etc.) If the process of writing a test means significantly more work than the code itself, and I'm pretty sure I can manually test some core cases, then I'll occasionally cut corners.
That said, mocking complexity is often your friend in this process. And even things that seem complex can be tested. My recent challenge-to-self is to have a smoke tester be able to test its own smoke testing ability. C.f. CPAN::Reporter::Smoker. It actually bundles a tiny mini-cpan inside the test suite for testing.
Some "defensive" coding and exception coding (invalid value testing). Often, things like "open or die". In my opinion, a pedantic focus on test-first shouldn't get in the way of good practices and momentum. I don't want to write a test to fake a file that can't be opened just to let me "test" before I write the "or die" part. Running coverage tests periodically with Devel::Cover is important to keep me honest about going back and writing tests later for those things I just threw in when I was on a roll.
Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.