如何为 Perl 脚本编写单元测试用例

How to write unit test cases for a Perl script

我可以为 Perl 模块编写单元测试 test_case.t ModuleOne.pm

test_case.t

use strict;
use warnings;
use Test::More;
use Test::Cmd;
use ModuleOne; # Included the module here

my $ret = ModuleOne::methodone(args);
is($ret->{val}, 1, "Checking return value"); # success 

我正在尝试为 perl 脚本实现相同的单元测试用例 script_one.pl

script_one.pl

use strict;
use warnings;
use ModuleOne;

my $NAME;
my $ID;

# get parameters
GetOptions (
 "name" => $NAME,
 "emp_id" => $ID,
)

validate_params();

sub validate_params {
   # this method will validate params 
}

sub print_name {
   # this method will print name 
}

如何在 test_case.t 中包含此 perl 文件 script_one.pl 并为方法 validate_paramsprint_name 编写测试用例?

There are a couple of options. One is to use Test::Script to see if your code compiles and 运行s, and does some stuff. It's more of an integration test than a unit test though, and if you have external dependencies like writing to the file system, it's tough to mock those away like this.

Since you've got subs in the script, the easiest way is probably to require or do the script in your test file, maybe inside a different package (but that doesn't really matter). You can then call those functions, because they are in one of your namespaces.

use strict;
use warnings;
use Test::More;

package Foo {
    do 'script_one.pl';
};

is Foo::print_name, 'foo', 'prints the right name';

This way you can mock dependencies more easily and you get some more control. The only thing that might be tricky is code that's not in subs and will be 运行 at invocation, like the call to validate_params. You could just use Capture::Tiny to brush that under the rug.

The best option though is to not have functions in your script. Just make another module that has those functions, and call it in your script. It's fine to have a script like the following.

#!/usr/bin/env perl
use strict;
use warnings;
use My::Modules::Foo;

My::Modules::Foo->run; # or ::run()

It doesn't matter if it's OOP or not. The idea will be the same. If you encapsulate it properly, you can unit-test all your code without ever using that script.

Regarding the GetOpts stuff, those variables can be lexicals to the script, but your naming with the capital letters and the lack of arguments to the validate_params call indicate that they are really package-wide and are used inside the function.不要那样做。 Use arguments to the subs. Put all the subs in a package, then have GetOpts in the script, and pass the options as arguments to the function.

That way you can test everything and really don't need the script.