用于连接到 Perforce 的 Perl 单元测试——连接到服务器失败;检查 $P4PORT
Perl Unit Test for Connection to Perforce -- Connect to Server Failed; check $P4PORT
我正在编写一个 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;
}
当我 运行 "perl p4_connect.pl"
时,Perl 脚本执行良好,没有抛出任何错误。
然而,当我将 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.
这是单元测试 (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
这就是我的包 (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;
}
我的单元测试哪里出错了?任何建议都有帮助。
您正在混合面向对象的 Perl 和函数式 Perl,您已成为它的牺牲品。
当你用箭头运算符 ->
将函数作为方法调用时,Perl 将左侧的内容作为函数的第一个参数传递给函数1 .如果是包名,那只是包名。
package Foo;
sub frobnicate{ print "@_" }
package main;
Foo->frobnicate(1, 2, 3);
它的输出将是
Foo 1 2 3
因此,在您的情况下,connect_perforce
将获得此分配:
my ($clientname, $p4port) = ('Perforce', 'johndoe', 'icmanage:1667' );
因此变量将具有这些值:
$clientname: 'Perforce'
$p4port: 'johndoe'
你的 'icmanage:1667'
字符串丢失了。
当你没有对象时,不要使用箭头。调用此函数(不是方法!)的正确方法是使用包含包的完全限定名称。
my $p4 = Perforce::connect_perforce('johndoe', $p4port);
我已经删除了这个相当奇怪的 qw()
。它会给你一个文字 $p4port
而不是值,所以这是你接下来会遇到的另一个错误。
由于我们已经确定您没有 class,而是一个模块,因此您也不想使用 can_ok
。这不是适合您的用例的测试类型。相反,只需调用我上面显示的函数,然后使用返回值进行有用的测试。如果该函数不存在,测试程序将失败,您会注意到。
BEGIN { use_ok('Perforce'); }
my $p4 = Perforce::connect_perforce('johndoe', 'icmanage:1667');
isa_ok($p4, 'P4'); # I guess..
有关面向对象和模块的更多信息,也请查看 perlobj and perlootut, perlnewmod and Exporter. Perlmaven has some good articles。
1) 做的更多,但这里不相关
我正在编写一个 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;
}
当我 运行 "perl p4_connect.pl"
时,Perl 脚本执行良好,没有抛出任何错误。
然而,当我将 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.
这是单元测试 (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
这就是我的包 (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;
}
我的单元测试哪里出错了?任何建议都有帮助。
您正在混合面向对象的 Perl 和函数式 Perl,您已成为它的牺牲品。
当你用箭头运算符 ->
将函数作为方法调用时,Perl 将左侧的内容作为函数的第一个参数传递给函数1 .如果是包名,那只是包名。
package Foo;
sub frobnicate{ print "@_" }
package main;
Foo->frobnicate(1, 2, 3);
它的输出将是
Foo 1 2 3
因此,在您的情况下,connect_perforce
将获得此分配:
my ($clientname, $p4port) = ('Perforce', 'johndoe', 'icmanage:1667' );
因此变量将具有这些值:
$clientname: 'Perforce'
$p4port: 'johndoe'
你的 'icmanage:1667'
字符串丢失了。
当你没有对象时,不要使用箭头。调用此函数(不是方法!)的正确方法是使用包含包的完全限定名称。
my $p4 = Perforce::connect_perforce('johndoe', $p4port);
我已经删除了这个相当奇怪的 qw()
。它会给你一个文字 $p4port
而不是值,所以这是你接下来会遇到的另一个错误。
由于我们已经确定您没有 class,而是一个模块,因此您也不想使用 can_ok
。这不是适合您的用例的测试类型。相反,只需调用我上面显示的函数,然后使用返回值进行有用的测试。如果该函数不存在,测试程序将失败,您会注意到。
BEGIN { use_ok('Perforce'); }
my $p4 = Perforce::connect_perforce('johndoe', 'icmanage:1667');
isa_ok($p4, 'P4'); # I guess..
有关面向对象和模块的更多信息,也请查看 perlobj and perlootut, perlnewmod and Exporter. Perlmaven has some good articles。
1) 做的更多,但这里不相关