package MyCode; use strict; use warnings; sub run { # Main routine here } ... rest of implementation here... __PACKAGE__->run() unless caller(); 1; #### package Sample; use strict; use warnings; use GetOpt::Long; __PACKAGE__->run() unless caller(); sub run { my($should_foo); die "usage: Sample.pm [--foo|--bar]\n" unless(GetOptions('foo' => \$should_foo, 'bar' => \$should_bar); my $value = $should_foo ? foo() : bar(); print $value; } sub foo { return "Foo to you too\n"; } sub bar { return "The best bar none\n"; } 1; #### use Test::More tests=>1; use Test::Exception; use Sample; is Sample->bar(), "The best bar none\n", 'bar() works'; is Sample->foo(), "Foo to you too\n", 'foo() works'; local @ARGV; # now undef dies_ok { Sample->run() } 'no args dies as expected'; like $@, qr/^usage:/, 'got a usage message';