http://www.perlmonks.org?node_id=749581

On my most-recent project, I did something I had not properly done before:   I built an ongoing test-suite, during the development process. As each new feature was added to the code, and sometimes before, I immediately wrote a test-case for it. And I didn't proceed until that test, and all preceding tests, “ran clean.”

This had immediate effects:

  1. Initial code-writing took about twice as long as before.
    • Overall development time was far less.
  2. During this process, “regression” of previously-written code happened at unexpected (and frequent) times.
  3. Writing tests in this way, and at this time, forces you to think more slowly and more deliberately about the code that you write, and thus to write much better code.
    • The “payback” was so obvious, and so immediate, that I became somewhat obsessed, so to speak, with writing and maintaining those test cases. I found myself feeling quite nervous about “putting my full weight upon” a new piece of code that wasn't tested. (Also, once you get into it, writing new tests is engaging and fun.)
  4. The bugs that were uncovered were usually nasty and subtle. I would not have discovered them except under the least-desirable circumstances.
    • The bugs that weren't uncovered were, for the most part, “merely annoying.”
  5. When the code was finished, it was reliable, and I didn't worry about doing demos.
    • In spite of all this, a demo is still the best test-case you can ever have.
    • The probability of a bug appearing during a demo is in direct proportion to your smugness that it won't, plus 100%.   :-D

Fortunately for all of us, Perl makes it very easy to write tests. A test program is simply a Perl program, written using a test-module such as Test::Most, Test::Memory::Cycle, Test::Exception, or Test::Class. You see test-suites run every time you install anything from CPAN, so it's a very well-developed system. When you start writing test-suites of your own, you really appreciate what it means when you see hundreds or even thousands of test-cases flying by during one of those installs. The fact that “CPAN is highly reliable” is anything but an accident.

What I do (and it's not the only way nor necessarily the best way to do it) is simply to create a t subdirectory, for “tests,” with number-prefixed subdirectories and number-prefixed test-programs in each. (This is done because the test files and directories will be traversed in-order.) Then, I run these with the command:   prove -r.

A test-case is very simple, really:   it's both a list of things that you do expect to happen, and things that you don't. It's a test of things that should cause an exception to occur, and things that shouldn't. It's a test of the “edge cases,” the sublime, and the ridiculous.

For web-based applications you can go further. Modules such as Test::WWW::Mechanize can perform an entire web-interaction sequence. Or you have things like Test::WWW::Declare, which is based around the notion of defining a “flow.”

My point here is not to enumerate all of the things that you can do with Perl testing. (There are, today, 805 CPAN modules whose name begins with “Test::” ...) Rather, it is:  “You should do this. It really works.” Sure, I'm not the first person to say it. I'm just one who took about twenty years to really listen.   ;-) ;-) :-D