Jon*_*n J 4 perl perforce unit-testing
我正在编写一个P4Perl脚本来连接Perforce服务器并自动执行Perforce命令.随着子程序的开发以访问Perforce,我也在开发单元测试来验证它们.我是Perl和单元测试的新手.
这是我与Perforce建立连接的子例程.文件名是p4_connect.pl
use warnings;
use strict;
use P4;
my $clientname = "johndoe"
my $p4port = "icmanage:1667"
main();
sub main {
my $status;
$status = connect_perforce($clientname, $p4port);
};
sub connect_perforce {
my ($clientname, $p4port) = @_;
my $status;
my $p4 = new P4;
$p4->SetClient( $clientname );
$p4->SetPort( $p4port );
$status = $p4->Connect() or die( "Failed to connect to Perforce Server" );
return $status;
}
Run Code Online (Sandbox Code Playgroud)
运行时Perl脚本执行正常"perl p4_connect.pl"
,不会抛出任何错误.
但是,当我将connect_perforce
子例程移动到包模块(Perforce.pm)
并(perforce.t)
为其编写单元测试时,我遇到了以下错误:
username@hostname% perl -Ilib t/perforce.t
ok 1 - use Perforce;
ok 2 - Perforce->can('connect_perforce')
Connect to server failed; check $P4PORT.
TCP connect to johndoe failed.
Servname not supported for ai_socktype
Failed to connect to Perforce Server at lib/Perforce.pm line 16.
Run Code Online (Sandbox Code Playgroud)
这是单元测试的(perforce.t)
样子:
use Perforce;
use warnings;
use strict;
use Test::More qw(no_plan);
use P4;
BEGIN { use_ok('Perforce'); } #package can be loaded
can_ok('Perforce', 'connect_perforce'); #subroutine connect_perforce exists
my $p4port = "icmanage:1667";
my $p4 = Perforce->connect_perforce(qw(johndoe $p4port)); #accessing the connect_perforce() subroutine
Run Code Online (Sandbox Code Playgroud)
这就是我的包的(Perforce.pm)
样子:
package Perforce;
use warnings;
use strict;
use P4;
sub connect_perforce {
my ($clientname, $p4port) = @_;
my $status;
my $p4 = new P4;
$p4->SetClient( $clientname );
$p4->SetPort( $p4port );
$status = $p4->Connect() or die( "Failed to connect to Perforce Server" );
return $status;
}
Run Code Online (Sandbox Code Playgroud)
我的单元测试在哪里出错了?任何建议都有帮助.
你正在混合面向对象的Perl和功能性Perl,你已成为它的受害者.
当您使用箭头操作符调用函数作为方法时->
,Perl将左侧的东西作为函数1的第一个参数传递.如果是包名,那就是包名.
package Foo;
sub frobnicate{ print "@_" }
package main;
Foo->frobnicate(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
这个的输出将是
Foo 1 2 3
Run Code Online (Sandbox Code Playgroud)
所以在你的情况下,connect_perforce
将得到这个任务:
my ($clientname, $p4port) = ('Perforce', 'johndoe', 'icmanage:1667' );
Run Code Online (Sandbox Code Playgroud)
所以变量将具有以下值:
$clientname: 'Perforce'
$p4port: 'johndoe'
Run Code Online (Sandbox Code Playgroud)
你的'icmanage:1667'
字符串会丢失.
如果没有对象,请不要使用箭头.调用此函数的正确方法(它不是方法!)是使用包括包的完全限定名称.
my $p4 = Perforce::connect_perforce('johndoe', $p4port);
Run Code Online (Sandbox Code Playgroud)
我删除了这个相当奇怪qw()
.它会给你一个文字$p4port
而不是值,所以这是你接下来会遇到的另一个错误.
既然我们已经确定你没有一个类,而是一个模块,你也不想使用它can_ok
.这不是对您的用例的正确测试.相反,只需调用上面显示的函数,然后使用返回值进行有用的测试.如果该功能不存在,测试程序将失败,您会注意到.
BEGIN { use_ok('Perforce'); }
my $p4 = Perforce::connect_perforce('johndoe', 'icmanage:1667');
isa_ok($p4, 'P4'); # I guess..
Run Code Online (Sandbox Code Playgroud)
有关面向对象和模块的更多信息,请查看perlobj和perlootut,perlnewmod和Exporter.Perlmaven也有一些好文章.
1)它做得更多,但这与此无关