Should I Offer a Testing Class?

Ovid on 2008-06-01T10:46:02

I'm back from a week in the US and had a fabulous time celebrating the birthdays of two of my closest friends. Because I was on vacation, I did what any self-respecting geek would do: I taught someone automated testing.

The basic problem she had was the same problem I had when I got started in testing, but with an added twist. Many people like the idea of testing but they need that initial push. Just trying to test a 'Point' class or a log file parser sounds nice, but I keep hearing people say 'yeah, but that really doesn't apply to what I do. These people (like myself, years ago), need that first push. My friend's problem was like this, but with the added problem that the code she has to maintain is spaghetti with little modularity. Not an easy first task. It's basically programs with the following standard structure:

use some modules

global variable declarations

command line processing

if/else chain and/or a loop construct

a bunch of subs which refer to globals

This is such a common pattern in code that it makes me want to scream, but fortunately, it's not as hard to test as you might think.

You could use Expect (something I find painful), but if you're willing to give it a go, you can follow the standard strategy of just trying to load the program in a test program. Once you can get require_ok to pass, you can then start testing (though this really depends on how bad the code is). It works like this:

#!/usr/bin/perl

use strict;
use warnings;

use Test::Most 'no_plan', 'die';

# stop some modules from loading
$INC{'Some/TroubleSome/Module.pm'} = "loaded by $0";

require_ok 'bin/script_to_be_tested.pl';

{
    package Some::TroubleSome::Module;

    sub get_config {
        return {
            user => 'test',
            site => 'example.com',
        };
    }
}


# override functions in other modules

my ( $PROCESS_IN, $PROCESS_OUT );
{
    package Another::TroubleSome::Module;
    no warnings 'redefined';

    sub process {
        $PROCESS_IN = shift;
        # fake results for unit testing
        $PROCESS_OUT = $results;
    }
}

# do some tests

With that, you then will likely need to take the core code in the program and wrap it in unless (caller) { ... }. With that, the block gets executed if called from the command line, but since caller will return true if loaded from the test program, the block won't get executed. This isn't a perfect setup, but neither is the mess of spaghetti that people who need this tend to have.

Which gets me down to my core point: I repeatedly find that people want to test, but don't know where to start. They need to learn how tests work before they can dig into their unique situations. That's why I'm toying with the idea of setting up a part-time test consultancy. Basically, I would be available on the occasional Saturday to lead a six-hour testing course, complete with exercises for programmers to work through. I already have some rough notes lined up for this and six hours would be easy to fill. The rough outline is something like this:

  • Basic testing with Test::More
  • Common test modules
  • Test::Harness and prove
  • Testing programs instead of modules
  • Testing databases
  • Managing large scale test suites
  • Test::Class

I do wonder, though, if there are enough programmers who care about testing and enough companies who understand its benefits to make this a worthwhile project to pursue. I want more people doing software testing. It will lower the company's costs and make the programmers turn out better code. This is important to me though I don't know if enough others feel the same way.

Note that if this project goes anywhere, it would strictly be a side project as I have no desire to leave the BBC. I love my job :)


i would be interested

groditi on 2008-06-01T14:54:55

If it happened that the class was in a geographically convenient location I would probably sign up if I had the time slot open. I'm pretty sure $work would e more than happy to pay for it too.

Re:i would be interested

Ovid on 2008-06-02T07:07:56

Ah, cool. Good to know there's some chance of me pulling this off :)

Another common problem

btilly on 2008-06-02T03:39:26

Is stopping testing at the point where you have a webserver involved.

What I mean is this. You write several modules. And give them all test suites. Then you add your web framework. And you start putting it all together. But all of the code that depends on the web framework is untested. Which means that if you're using an MVC pattern that the M has tests but the V and C parts do not.

Re:Another common problem

Ovid on 2008-06-02T07:06:51

And there's a common testing anti-pattern associated with this. It's great to unit test the V and C, but many people will mock up so much of the Web framework when running integration tests that it's easy to test something which isn't exhibiting real behavior. It's a frustrating problem that can be difficult to break out of, once encountered.

I'd say they'd be enough interest...

Adrian on 2008-06-02T13:24:20

... I did some classes a few years back covering the same sort of thing and got some reasonable interest. I'd say they'd be a lot more now since more folk are getting testing.