I maintain a couple of applications which have turned from proofs of concept into working products with real users. As with much code in the real world, parts of these applications are great. Parts need rethinking. Weird bugs lurk in corners, revealed by deployment issues, assumptions about incoming data, and the desire to respond to customer wants and needs.
It's a lot of fun, and it provides fertile ground for seeing the kinds of mistakes people make on small projects driven by customer feedback.
It almost goes without saying that proof of concept code has far too little test coverage.
I found a bug in one project after deployment today. (Deployment happened last night, when it should have happened in the morning, but that's a different story.) It was a misplaced parenthesis. Here's the diff:
- my ($status = $response->status_line) =~ tr/\r//d; + (my $status = $response->status_line) =~ tr/\r//d;
That's a very silly, very simple thing—an easy mistake to make. It's just a typo. I make a couple of dozen typos a day while coding, if not more.
This code is in a very simple class of about 60 lines that wraps around an
HTTP request/response pair and dispatches to the appropriate method when the
asynchronous response returns. It's very simple. It's a wrapper with a
process() method, and you could probably write it yourself from
It didn't have a test.
I understand the mindset of the person who wrote this. It's so simple, it almost can't fail. (It can only fail if it fails to compile.)
When I saw the error in our error logs, I had a fix in moments. Then I spent
another minute to ensure that this type of error would never happen again. Our
deployment strategy uses
dzil release, which runs all of the tests
and checks the Git checkout for sanity before releasing. A compilation error
like this—even in code without a test—will never happen again. Here
are the seven lines of code:
#!/usr/bin/env perl use Modern::Perl; use Test::More; use lib 'lib'; use Module::Pluggable search_path => [ 'MyApp' ]; require_ok( $_ ) for __PACKAGE__->plugins; done_testing;
I added this test to the other project I've been working on this week, and it caught a (small) bug too.
If you're not practicing rampant TDD for every file, package, and class you maintain, at least start with this one test file.
(Yes, static language fans: your compiler often helps you avoid this problem. Other times you have dynamic linking to consider.)