use 5.008;
use strict;
use warnings;

package Test::Class::GetoptControl;
our $VERSION = '1.100860';
# ABSTRACT: Command-line control of test class execution
use List::Util 'shuffle';
use Test::More;
use Test::Class;
use parent 'Getopt::Inherited';
use constant GETOPT => qw(
  include|i=s@ shuffle reverse

sub runtests {
    my $self    = shift;
    my @classes = $self->get_classes;
    if (@classes) {
    } else {
        diag 'No class meets the specification';

sub get_classes {
    my $self      = shift;
    my $test_info = Test::Class->_test_info;
    my @classes   = keys %$test_info;

    # first, if --include is given, filter out classes that aren't included
    my @include = @{ $self->opt('include') || [] };
    if (@include) {
        my %keep;
        for my $class (@classes) {
            for (@include) {
                $keep{$class}++ if index($class, $_) != -1;
        @classes = keys %keep;

    # now determine test class order
    if ($self->opt('shuffle')) {
        note '--shuffle takes precedence over --reverse'
          if $self->opt('reverse');
        note 'test order: shuffle';
        @classes = shuffle @classes;
    } elsif ($self->opt('reverse')) {
        note 'test order: reverse';
        @classes = reverse sort @classes;
    } else {
        note 'test order: sort';
        @classes = sort @classes;

        # Perl::Critic complains about "return sort ... "


=for stopwords GETOPT runtests

=for test_synopsis 1;

=head1 NAME

Test::Class::GetoptControl - Command-line control of test class execution

=head1 VERSION

version 1.100860


    package MyApp;
    use base qw(Test::Class::GetoptControl);

    package main;
    my $app = MyApp->new;

on the command-line:

    $ myapp --include FooTests --shuffle
    # test order: shuffle
    ok 1 - foobar


When inheriting from this class, your application gets the ability to control
the execution of test classes using command-line options.

=head1 METHODS

=head2 runtests

Calls C<get_classes()> to determine which test classes to run and in which
order, then runs them.

=head2 get_classes

Asks L<Test::Class> for information on all registered test classes, then
filters and sorts them by the criteria set in the command-line options.

=head2 GETOPT

Defines the specific command-line options for this class; see


=over 4

=item C<--include>

This option takes a string and can be given several times. It says that only
classes whose package name contains the string should be run. C<-i> is an
alias for this option. If no C<include> option is given, all test classes are


    $ myapp --include Foo
    $ myapp -i Foo
    $ myapp --include Foo --include Bar

=item C<--shuffle>

This options causes the test classes to be run in a random order. A note
saying so is printed as well.

=item C<--reverse>

This options causes the test classes to be run in reverse alphabetical package
name order. If neither C<--reverse> nor C<--shuffle> are given, tests are run
in alphabetical package name order. If both C<--reverse> and C<--shuffle> are
given, C<--shuffle> takes precedence and a note saying so is printed.

In any case, a note specifying the sort order is printed.



See perlmodinstall for information and options on installing Perl modules.


No bugs have been reported.

Please report any bugs or feature requests through the web interface at


The latest version of this module is available from the Comprehensive Perl
Archive Network (CPAN). Visit L<> to find a CPAN
site near you, or see

The development version lives at
Instead of sending patches, please fork this project using the standard git
and github infrastructure.

=head1 AUTHOR

  Marcel Gruenauer <>


This software is copyright (c) 2009 by Marcel Gruenauer.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.