Perl单元测试连接到Perforce——连接到服务器失败;检查$P4端口

Perl单元测试连接到Perforce——连接到服务器失败;检查$P4端口,perl,unit-testing,perforce,Perl,Unit Testing,Perforce,我正在编写一个P4Perl脚本,以连接到Perforce服务器并自动执行Perforce命令。随着访问Perforce的子程序的开发,我也在开发单元测试来验证它们的正确性。我对Perl和单元测试都是新手 这是我的子程序,用于建立与Performance的连接。文件名为p4\u connect.pl use warnings; use strict; use P4; my $clientname = "johndoe" my $p4port = "icmanage:1667" main();

我正在编写一个P4Perl脚本,以连接到Perforce服务器并自动执行Perforce命令。随着访问Perforce的子程序的开发,我也在开发单元测试来验证它们的正确性。我对Perl和单元测试都是新手

这是我的子程序,用于建立与Performance的连接。文件名为
p4\u 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;
}
当我运行
“Perl p4_connect.pl”
时,Perl脚本执行良好,不会引发任何错误

但是,当我将
connect\u 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.
这就是单元测试
(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
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;
}
这就是我的软件包
(Perforce.pm)
的外观:

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
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;
}

关于单元测试,我哪里出了问题?任何建议都是有帮助的。

您将面向对象的Perl和函数式Perl混合在一起,您已经成为它的受害者

当您使用箭头操作符
->
将函数作为方法调用时,Perl会将左侧的内容作为第一个参数传递给function1。对于包名,这只是包名

package Foo;
sub frobnicate{ print "@_" }

package main;
Foo->frobnicate(1, 2, 3);
这个的输出将是

Foo 1 2 3
因此,在您的情况下,
connect\u perforce
将获得以下分配:

my ($clientname, $p4port) = ('Perforce', 'johndoe', 'icmanage:1667' );
因此变量将具有以下值:

$clientname: 'Perforce'
$p4port:     'johndoe'
您的
'icmanage:1667'
字符串将丢失

如果没有对象,请不要使用箭头。调用此函数(它不是方法!)的正确方法是使用包含包的完全限定名

my $p4 = Perforce::connect_perforce('johndoe', $p4port);
我删除了这个相当奇怪的
qw()
。它将给您一个文本
$p4port
,而不是值,因此这是您接下来会遇到的另一个错误

因为我们已经确定您没有类,而是模块,所以您也不想使用
can\u ok
。这不是适合您的用例的测试类型。相反,只需像上面显示的那样调用函数,然后使用返回的值进行有用的测试。如果函数不存在,测试程序将失败,您会注意到

BEGIN { use_ok('Perforce'); }

my $p4 = Perforce::connect_perforce('johndoe', 'icmanage:1667');

isa_ok($p4, 'P4'); # I guess..
有关对象定向和模块的更多信息,请参阅和和。帕尔马文也有



1) 它做的更多,但这与此处无关

不确定这是否相关,但您的一个程序将
$p4port
设置为
icmanage.com:1667
,而另一个程序将其设置为
icmanage:1667
。顺便说一句,消息“Servname不支持ai_socktype”使您的问题听起来非常类似于。这条消息让我觉得某些网络软件库正在网络配置文件中查找“icmanage”服务?非常抱歉,这是一个输入错误。它已被及时更正
new P4
应为
P4->new
,并带有箭头。这是代码中唯一应该有箭头的地方,因为间接对象表示法不明确。:)