Perl Unit Test for connecting to Perforce - server connection failure; check out $ P4PORT

I am writing a P4Perl script to establish a connection to a Perforce server and automate the execution of Perforce commands. In addition to developing routines for accessing Perforce, I also develop unit tests to test them. I am new to Perl and unit testing.

This is my routine to establish a connection with Perforce. File Name 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; } 

The perl script runs fine when I run "perl p4_connect.pl" , no errors occur.

However, when I moved the connect_perforce routine to a batch module (Perforce.pm) and wrote a unit test (perforce.t) , I ran into these errors:

 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. 

Here's what unit test (perforce.t) looks like:

 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 

And here is what my package (Perforce.pm) looks like:

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

Where am I wrong about my unit test? Any suggestions are helpful.

+4
source share
1 answer

You mix Object Oriented Perl with Functional Perl, and you fall prey to this.

When you call a function as a method with an arrow -> , Perl passes the item on the left as the first argument to function 1 . In the case of a package name, this is simply the name of the package.

 package Foo; sub frobnicate{ print "@_" } package main; Foo->frobnicate(1, 2, 3); 

The result of this will be

 Foo 1 2 3 

So, in your case, connect_perforce will get this assignment:

 my ($clientname, $p4port) = ('Perforce', 'johndoe', 'icmanage:1667' ); 

Thus, the variables will have the following values:

 $clientname: 'Perforce' $p4port: 'johndoe' 

And your string 'icmanage:1667' is lost.

If you do not have objects, do not use the arrow. The correct way to call this function (this is not a method!) Is to use the fully qualified name, including the package.

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

I deleted this rather strange qw() . This will give you the literal $p4port instead of the value, so this will be another mistake you would encounter further.

Since we have established that you do not have a class, but rather a module, you also do not want to use can_ok . This is not the right test for your use case. Instead, just call the function as shown above, and then run useful tests with a return value. If the function is not there, the test program will fail, and you will notice.

 BEGIN { use_ok('Perforce'); } my $p4 = Perforce::connect_perforce('johndoe', 'icmanage:1667'); isa_ok($p4, 'P4'); # I guess.. 

For more information on object orientation and modules, see perlobj and perlootut , perlnewmod, and Exporter . Perlmaven has some good articles .


1) He does more, but it is not relevant here

+5
source

All Articles