One interesting quirk of Pinboard is a complete absence of unit tests. I used to be a die-hard believer in testing, but in Pinboard tried a different approach, as an experiment. Instead of writng tests I try to be extremely careful in coding, and keep the code size small so I continue to understand it.
I've found my defect rate to be pretty comparable to earlier projects that included extensive test suites and fixtures, but I am much more productive on Pinboard
Its great that this approach is working for him, but this may not work in a decent sized project with multiple people working on it. I prefer a safety net of test cases in such cases.
The problem is that unit tests aren't for today. Unit tests are for 3 years from now when you've forgotten how a system behaves and you need to make a major change to it (nb: I'm not talking TDD here). When you get done with that change (and every company I've worked at with no unit tests has), you'll look back and realize you had three choices:
1. Write the unit tests while the code was fresh. Ideally, you wrote well designed unit tests so you didn't have to constantly deal with maintaining crappy test code. Unfortunately, most test code doesn't seem to be well-written, DRY code, so you spend a lot of time in the interum maintaining it.
2. Figure the code out again when you need to change it (likely somebody else is doing the figuring out by then) and write unit tests that show current behavior. The "figuring out" step is always nastier than you expect.
3. Start digging and hope you come out the other side with something reasonably similar to what you started with.
The trick is figuring out which one optimizes best for your business. Pinboard might be able to get away with #3. Air traffic control may have no choice but to be #2 (did people write unit tests way back then? I know I didn't write any unit tests on my Atari 600 in '83 :).
My unit tests are half for today—they actually let me code faster and better—and half for next month, when I discover a much better way to do things and reorganize my code savagely.
3 years from now? That's just a bonus which lets me feel smug. The real payoff was immediate, and did not involve any virtuous self-discipline.
On point 2 - I tend to find that if I write unit tests at the same time as I write code then the code is structured to be easier to unit test. Writing unit tests for code that has been developed without any concerns for unit testing can be a complete nightmare.
It is true that unit testing code that was not designed for testing can be difficult, but it is certainly possible. Java reflection can set data values in private fields for times when the original class did not include a setter method for testing. Commerical solutions, like http://tinyurl.com/4rabnef, provide stubbing frameworks to replace method calls at runtime and inject test data without rewriting the original code.
I think the size of a test suite should be dependent on the size of the project and team, as you stated. Most TDD advocates are overboard with it imo; a test case should certainly be written when a regression occurs to make sure it doesn't happen again, and tests should be filled in in other cases as time and circumstances permit (recognizing that tests are an important part of the application that you can't just shove off until your favorite theorized utopian corporate culture is realized), but I've never been a big fan of making the development process all about tests. I think it's overzealous and ultimately just burns people out on testing, causing them to get lazy and go almost test-less when they have the option. There are times when it's better to discard form and just write some code straight up without descending into a mire of testing beforehand.
I've often found that dogma is useful for the beginner, because practice is needed. When you mindlessly apply something, you focus on the application, and not if it's appropriate.
Once you've got the application down fine, then you have some experience to base your decision on when is and is not a good time to actually apply things.
> Instead of writng tests I try to be extremely careful in coding, and keep the code size small so I continue to understand it.
Amen, brother. I feel exactly the same way. I find this approach works perfectly 99%+ of the time, and regardless, I end up spending way way less time writing and maintaining code because of it. Understand what you're doing, and why, and you reap benefits not just at the tactical momentary level, but long term and architecturally as well. Understand the codebase really well, and it's much easier to diagnose issues that happen in production or at a larger scale.
Yes, this approach is ideal when you are one person working consistently on the same project, and have much of the design in your head, which is feasible when you keep the code size small.
It suffers when you have multiple people working simultaneously, or if you have to take a break before returning to the project. In those case, a secondary automated statement of what the system should do is quite useful.
I've found my defect rate to be pretty comparable to earlier projects that included extensive test suites and fixtures, but I am much more productive on Pinboard
Its great that this approach is working for him, but this may not work in a decent sized project with multiple people working on it. I prefer a safety net of test cases in such cases.
EDIT : Formatting