Renumbering tests

Ovid on 2005-11-20T21:42:06

Back in the early 90s when I was doing BASIC programming, I was soooo happy when I finally used a system which allowed me to automatically renumber my program lines. It made programming much easier. Today, I routinely find myself wedging tests between other tests since I number my tests.

10_class_trait.t
15_test_imports.t
20_trait_overload.t
30_trait_composition.t
40_Trait_Config_test.t
50_Trait_SUPER_test.t
60_Trait_mod_perl_test.t
70_Trait_SUPER2_test.t
80_Class_Trait_Lib_tests.t
90_trait_rename_does.t
91_trait_performs.t
99_trait_errors.t

Today I got fed up with that and wrote a simple test renumbering program. You may not find it useful but it does exactly what I need. Admittedly, tests should run in any order but I have a convention that lower numbered test failures should be addressed first as they're likely the ones causing other test errors.

The following is a bit of a hack and it's certainly not portable, but then, I didn't really right it for anyone else :)

#!/usr/bin/perl 

use strict;
use warnings;

use Getopt::Long;
my $dir      = ".";
my $test_num = 10;
my $step     = 10;

GetOptions(
    "dir=s"   => \$dir,
    "start=i" => \$test_num,
    "step=i"  => \$step,
    "dry"     => \my $dry_run,
    "svn"     => \my $svn,
);

unless ( -d $dir ) {
    die "I cannot find the directory ($dir)";
}

my @tests = glob "$dir/*.t";
unless (@tests) {
    die "No tests found in ($dir)";
}

@tests =
  sort grep { /^\d+/ }
  map { s{^\Q$dir/}{}; $_ } @tests;    # only take numbered tests

my $digits = length( $test_num + ( $step * @tests ) );

foreach my $test (@tests) {
    my $new_name = $test;
    $new_name =~ s{^\d+(.*)$}
                  {
                     my $name = sprintf "%0${digits}d$1", $test_num;
                     $test_num += $step;
                     $name
                  }e;

    next if $new_name eq $test;
    my @command = ( "mv", "$dir/$test", "$dir/$new_name" );
    if ($svn) {
        unshift @command, "svn";
    }
    if ($dry_run) {
        print "@command\n";
    }
    else {
        system(@command);
    }
}


Test::Manifest

brian_d_foy on 2005-11-20T22:59:02

I wrote Test::Manifest because I think ordering tests by their filename is silly. Not only that, by specifying which tests to run and which order to run them in using a separate file makes it easy to turn off tests while I'm developing. :)

Re:Test::Manifest

mr_bean on 2005-11-21T03:08:44

Does this work with Module::Build? I see references to Makefile in the pod?

Re:Test::Manifest

brian_d_foy on 2005-11-21T04:53:27

It will work when somebody patches it for Module::Build, which I don't use (at least not yet).

watch for collisions

jmm on 2005-11-21T15:30:58

In theory, you should never have two tests that have the same name, differing only in the sequence number portion of the name. If, in practice, you ever did however, the rename could cause problems if the first one processed is being renamed to have the old sequence number of the second one.