I'm able to write unit tests test_case.t
for a Perl Module 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
I'm trying the achieve the same unit test cases for a perl script 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
}
How can I include this perl file script_one.pl
in test_case.t
and write test cases for methods validate_params
and print_name
?
There are a couple of options. One is to use Test::Script to see if your code compiles and runs, 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 run 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. Don't do that. Use arguments to the sub
s. 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With