Class: Test::Mini::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/Test/Mini/Runner.pm

Overview

Default Test Runner.

The Test::Mini::Runner is responsible for finding and running the appropriate tests, setting up output logging, and returning an appropriate status code. For those looking to write tests with this framework, the points of note are as follows:

  • Tests are run automatically at process exit.

  • All test cases (subclasses of TestCase) that have been loaded at that time will be considered. This includes indirect subclasses.

  • Within each test case, all methods defined with a name matching /^test.+/ will be run.

    • Each test will run in its own test case instance.

    • Tests will be run in random order.

    • #setup will be called before each test is run.

    • #teardown will be called after each test is run.

    • Inherited tests are not run.

  • Tests may be run via `prove`, by loading (via use, do or require) the files into another script, or by simply executing a file containing a test case in the Perl interpreter.

    • If you want to use a non-TAP output logger, `prove` is not an option.

  • Options may be passed in either as command line options, or as environment variables.

    • Environment variable names are prefixed with ‘TEST_MINI_’.

    • Valid options are:

      • verbose - Specifies the logger’s verbosity.

      • filter - Only tests with names matching this pattern should be run.

      • logger - Specifies an alternate output logger class.

      • seed - Specifies a random number seed; used to specify repeatable test orderings.

Attribute Accessors (collapse)

Test Run Hooks (collapse)

Callbacks (collapse)

Class Method Summary (collapse)

Class Method Details

+ new($class, %args)

Constructor. Arguments may be provided explicitly to the constructor or implicitly via either @ARGV (parsed by Getopt::Long) or environment variables (“TEST_MINI_$option”).

Parameters:

  • (Hash) %args

    Initial state for the new instance.

Options Hash (%args):

  • (Object) verbose — default: 0

    Logger verbosity.

  • (String) filter — default: ''

    Test name filter.

  • (Class) logger — default: Test::Mini::Logger::TAP

    Logger class name.

  • (Integer) seed — default: a random number +< 64_000_000+

    Randomness seed.



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/Test/Mini/Runner.pm', line 52

sub new {
    my ($class, %args) = @_;

    my %argv = (
        verbose   => $ENV{TEST_MINI_VERBOSE} || 0,
        filter    => $ENV{TEST_MINI_FILTER}  || '',
        logger    => $ENV{TEST_MINI_LOGGER}  || 'Test::Mini::Logger::TAP',
        seed      => $ENV{TEST_MINI_SEED}    || int(rand(64_000_000)),
    );

    GetOptions(\%argv, qw/ verbose=s filter=s logger=s seed=i /);
    return bless { %argv, %args, exit_code => 0 }, $class;
}

Instance Method Details

- error($self, $tc, $test, $e)

Callback for dying tests.

Parameters:

  • (Class) $tc

    The test case owning the test method.

  • (String) $test

    The name of the test with an error.

  • (Test::Mini::Exception) $e

    The exception object.



226
227
228
229
230
# File 'lib/Test/Mini/Runner.pm', line 226

sub error {
    my ($self, $tc, $test, $e) = @_;
    $self->{exit_code} = 1 unless $self->{exit_code};
    $self->logger->error($tc, $test, $e);
}

- exit_code($self)

Exit code, representing the status of the test run.

Returns:

  • Exit code, representing the status of the test run.



93
94
95
96
# File 'lib/Test/Mini/Runner.pm', line 93

sub exit_code {
    my $self = shift;
    return $self->{exit_code};
}

- fail($self, $tc, $test, $e)

Callback for failing tests.

Parameters:

  • (Class) $tc

    The test case owning the test method.

  • (String) $test

    The name of the failed test.

  • (Test::Mini::Exception::Assert) $e

    The exception object.



215
216
217
218
219
# File 'lib/Test/Mini/Runner.pm', line 215

sub fail {
    my ($self, $tc, $test, $e) = @_;
    $self->{exit_code} = 1 unless $self->{exit_code};
    $self->logger->fail($tc, $test, $e);
}

- filter($self)

Test name filter.

Returns:

  • Test name filter.



75
76
77
78
# File 'lib/Test/Mini/Runner.pm', line 75

sub filter {
    my $self = shift;
    return $self->{filter};
}

- logger($self)

Logger instance.

Returns:

  • Logger instance.



81
82
83
84
# File 'lib/Test/Mini/Runner.pm', line 81

sub logger {
    my $self = shift;
    return $self->{logger};
}

- pass($self, $tc, $test)

Callback for passing tests.

Parameters:

  • (Class) $tc

    The test case owning the test method.

  • (String) $test

    The name of the passing test.



195
196
197
198
# File 'lib/Test/Mini/Runner.pm', line 195

sub pass {
    my ($self, $tc, $test) = @_;
    $self->logger->pass($tc, $test);
}

- run($self)

Begins the test run. Loads and instantiates the test output logger, then dispatches to #run_test_suite (passing the #filter and #seed, as appropriate).

Returns:



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/Test/Mini/Runner.pm', line 105

sub run {
    my ($self) = @_;
    my $logger = $self->logger;
    try {
        eval "require $logger;" or die $@;
    }
    catch {
        eval "require Test::Mini::Logger::$logger;" or die $@;
    };

    $logger = $logger->new(verbose => $self->verbose);
    $self->{logger} = $logger;

    return $self->run_test_suite(filter => $self->filter, seed => $self->seed);
}

- (Integer) run_test($self, $tc, $test)

Runs a specific test.

Parameters:

  • (Class) $tc

    The test case owning the test method.

  • (String) $test

    The name of the test method to be run.

Returns:

  • (Integer)

    The number of assertions called by the test.



178
179
180
181
182
183
184
185
186
187
# File 'lib/Test/Mini/Runner.pm', line 178

sub run_test {
    my ($self, $tc, $test) = @_;
    $self->logger->begin_test($tc, $test);

    my $instance = $tc->new(name => $test);
    my $assertions = $instance->run($self);

    $self->logger->finish_test($tc, $test, $assertions);
    return $assertions;
}

- run_test_case($self, $tc, @tests)

Runs tests in a test case.

Parameters:

  • (Class) $tc

    The test case to run.

  • (Array<String>) @tests

    A list of tests to be run.



159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/Test/Mini/Runner.pm', line 159

sub run_test_case {
    my ($self, $tc, @tests) = @_;
    $self->logger->begin_test_case($tc, @tests);

    $self->{exit_code} = 127 unless @{[
        (@tests, grep { $_->isa($tc) } @{ mro::get_isarev($tc) })
    ]};

    $self->run_test($tc, $_) for shuffle @tests;

    $self->logger->finish_test_case($tc, @tests);
    return scalar @tests;
}

- run_test_suite($self, %args)

Runs the test suite. Finds subclasses of TestCase, and dispatches to #run_test_case with the name of each test case and a list test methods to be run.

Parameters:

  • (Hash) %args

Options Hash (%args):

  • (String) filter

    Test name filter.

  • (String) seed

    Randomness seed.

Returns:



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/Test/Mini/Runner.pm', line 130

sub run_test_suite {
    my ($self, %args) = @_;
    $self->logger->begin_test_suite(%args);

    srand($args{seed});
    my @testcases = @{ mro::get_isarev('Test::Mini::TestCase') };

    # Since mro::get_isarev is guaranteed to never shrink, we should "double
    # check" our testcases, to make sure that they actually are *still*
    # subclasses of Test::Mini::TestCase.
    # @see http://search.cpan.org/dist/perl-5.12.2/ext/mro/mro.pm#mro::get_isarev($classname)
    @testcases = grep { $_->isa('Test::Mini::TestCase') } @testcases;

    $self->{exit_code} = 255 unless @testcases;

    for my $tc (shuffle @testcases) {
        no strict 'refs';
        my @tests = grep { /^test.+/ && defined &{"$tc\::$_"}} keys %{"$tc\::"};
        $self->run_test_case($tc, grep { $_ =~ qr/$args{filter}/ } @tests);
    }

    $self->logger->finish_test_suite($self->exit_code);
    return $self->exit_code;
}

- seed($self)

Randomness seed.

Returns:

  • Randomness seed.



87
88
89
90
# File 'lib/Test/Mini/Runner.pm', line 87

sub seed {
    my $self = shift;
    return $self->{seed};
}

- skip($self, $tc, $test, $e)

Callback for skipped tests.

Parameters:

  • (Class) $tc

    The test case owning the test method.

  • (String) $test

    The name of the skipped test.

  • (Test::Mini::Exception::Skip) $e

    The exception object.



205
206
207
208
# File 'lib/Test/Mini/Runner.pm', line 205

sub skip {
    my ($self, $tc, $test, $e) = @_;
    $self->logger->skip($tc, $test, $e);
}

- verbose($self)

Logger verbosity.

Returns:

  • Logger verbosity.



69
70
71
72
# File 'lib/Test/Mini/Runner.pm', line 69

sub verbose {
    my $self = shift;
    return $self->{verbose};
}