【问题标题】:Perl Unit Test for Connection to Perforce -- Connect to Server Failed; check $P4PORT连接到 Perforce 的 Perl 单元测试 -- 连接到服务器失败;检查 $P4PORT
【发布时间】:2017-09-21 20:27:07
【问题描述】:

我正在编写一个 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;
}

我的单元测试哪里出错了?任何建议都有帮助。

【问题讨论】:

  • 不确定这是否相关,但您的一个程序将$p4port 设置为icmanage.com:1667,而另一个将其设置为icmanage:1667。顺便说一句,“ai_socktype 不支持 Servname”消息使您的问题听起来与 stackoverflow.com/questions/23079017/… 非常相似。该消息让我认为某些网络软件库正在尝试在网络配置文件中查找“icmanage”服务?
  • 非常抱歉,这是一个错字。它已得到适当的纠正
  • new P4 应该是带有箭头的P4->new。这是该代码中唯一应该有那个箭头的地方,因为间接对象表示法是模棱两可的。 :)

标签: perl unit-testing perforce


【解决方案1】:

你正在混合面向对象的 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 而不是值,所以这是你接下来会遇到的另一个错误。

既然我们已经确定你没有一个类,而是一个模块,你也不想使用can_ok。这不是适合您的用例的测试。相反,只需像上面显示的那样调用函数,然后对返回的值进行有用的测试。如果该功能不存在,则测试程序将失败,您会注意到。

BEGIN { use_ok('Perforce'); }

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

isa_ok($p4, 'P4'); # I guess..

有关面向对象和模块的更多信息,请查看perlobjperlootutperlnewmodExporter。 Perlmaven 也有 some good articles


1) 它做得更多,但这与这里无关

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多