How to pass arguments to Perl test when run through prove

When writing tests in Perl ecosystem, sometimes you need to write a test, which you can pass some arguments. For example, you may test with no arguments checks all files and if it as argument to specify the path to the file, then it will check only this one file.

Ie, the problem is that in Perl test variable @ARGV appeared values.

Here is an example test t/main.t:

use Test::More tests => 1;
use Data::Dumper;

pass('Loaded ok');

warn Dumper \@ARGV;

If you run this test using perl t/main.t one two three, then the conclusion will be seen that in the variable @ARGV got the values from the command line:

ok 1 - Loaded ok
$VAR1 = [

But if you run this same test using prove t/main.t one two three, then the output will be seen in an array @ARGV values from the command line do not hit and judging by SecTreas, prove perceived these arguments as arguments to the test, and as arguments to himself.

Here is the full output of work:

$VAR1 = [];
t/main.t .. ok
Cannot detect source of 'one'! at /usr/local/lib/perl5/5.28.1/TAP/Parser/ line 256.
    TAP::Parser::IteratorFactory::detect_source(TAP::Parser::IteratorFactory=HASH(0x55663d4f4300), TAP::Parser::Source=HASH(0x55663d61cdc0)) called at /usr/local/lib/perl5/5.28.1/TAP/Parser/ line 211
    TAP::Parser::IteratorFactory::make_iterator(TAP::Parser::IteratorFactory=HASH(0x55663d4f4300), TAP::Parser::Source=HASH(0x55663d61cdc0)) called at /usr/local/lib/perl5/5.28.1/TAP/ line 472
    TAP::Parser::_initialize(TAP::Parser=HASH(0x55663d6a11d8), HASH(0x55663d4f4390)) called at /usr/local/lib/perl5/5.28.1/TAP/ line 55
    TAP::Object::new("TAP::Parser", HASH(0x55663d4f4390)) called at /usr/local/lib/perl5/5.28.1/TAP/ line 130
    TAP::Object::_construct(TAP::Harness=HASH(0x55663ce11a90), "TAP::Parser", HASH(0x55663d4f4390)) called at /usr/local/lib/perl5/5.28.1/TAP/ line 852
    TAP::Harness::make_parser(TAP::Harness=HASH(0x55663ce11a90), TAP::Parser::Scheduler::Job=HASH(0x55663d33bf80)) called at /usr/local/lib/perl5/5.28.1/TAP/ line 651
    TAP::Harness::_aggregate_single(TAP::Harness=HASH(0x55663ce11a90), TAP::Parser::Aggregator=HASH(0x55663ce11880), TAP::Parser::Scheduler=HASH(0x55663d33be78)) called at /usr/local/lib/perl5/5.28.1/TAP/ line 743
    TAP::Harness::aggregate_tests(TAP::Harness=HASH(0x55663ce11a90), TAP::Parser::Aggregator=HASH(0x55663ce11880), "t/main.t", "one", "two", "three") called at /usr/local/lib/perl5/5.28.1/TAP/ line 558
    TAP::Harness::__ANON__() called at /usr/local/lib/perl5/5.28.1/TAP/ line 571
    TAP::Harness::runtests(TAP::Harness=HASH(0x55663ce11a90), "t/main.t", "one", "two", "three") called at /usr/local/lib/perl5/5.28.1/App/ line 548
    App::Prove::_runtests(App::Prove=HASH(0x55663ce093a8), HASH(0x55663d22f6c8), "t/main.t", "one", "two", "three") called at /usr/local/lib/perl5/5.28.1/App/ line 506
    App::Prove::run(App::Prove=HASH(0x55663ce093a8)) called at /usr/local/bin/prove line 13

The solution is to use ::

The team prove is a feature — what is written after the double colon symbol :: prove passes to run the test.

So if if you run the test with prove t/main.t :: one two three, we get the expected result:

$VAR1 = [
t/main.t .. ok
All tests successful.
Files=1, Tests=1,  0 wallclock secs ( 0.04 usr  0.01 sys +  0.09 cusr  0.02 csys =  0.16 CPU)
Result: PASS

Official documentation

Here's a snippet of the output perldoc prove about this feature prove:

  Arguments to Tests
    It is possible to supply arguments to tests. To do so separate them from
    prove's own arguments with the arisdottle, '::'. For example

     prove -v t/mytest.t :: --url

    would run t/mytest.t with the options '--url'. When
    running multiple tests they will each receive the same arguments.

Other articles