|
@@ -9,6 +9,7 @@ use utf8;
|
|
|
|
|
|
|
|
use parent qw/TAP::Parser/;
|
|
use parent qw/TAP::Parser/;
|
|
|
use Carp qw{cluck confess};
|
|
use Carp qw{cluck confess};
|
|
|
|
|
+use POSIX qw{floor};
|
|
|
|
|
|
|
|
use TestRail::API;
|
|
use TestRail::API;
|
|
|
use Scalar::Util qw{reftype};
|
|
use Scalar::Util qw{reftype};
|
|
@@ -74,6 +75,8 @@ Get the TAP Parser ready to talk to TestRail, and register a bunch of callbacks
|
|
|
It is worth noting that if neither step_results or case_per_ok is passed, that the test will be passed if it has no problems of any sort, failed otherwise.
|
|
It is worth noting that if neither step_results or case_per_ok is passed, that the test will be passed if it has no problems of any sort, failed otherwise.
|
|
|
In both this mode and step_results, the file name of the test is expected to correspond to the test name in TestRail.
|
|
In both this mode and step_results, the file name of the test is expected to correspond to the test name in TestRail.
|
|
|
|
|
|
|
|
|
|
+This module also attempts to calculate the elapsed time to run each test if it is run by a prove plugin rather than on raw TAP.
|
|
|
|
|
+
|
|
|
=cut
|
|
=cut
|
|
|
|
|
|
|
|
sub new {
|
|
sub new {
|
|
@@ -181,6 +184,10 @@ sub new {
|
|
|
if (defined($self->{'_iterator'}->{'command'}) && reftype($self->{'_iterator'}->{'command'}) eq 'ARRAY' ) {
|
|
if (defined($self->{'_iterator'}->{'command'}) && reftype($self->{'_iterator'}->{'command'}) eq 'ARRAY' ) {
|
|
|
$self->{'file'} = $self->{'_iterator'}->{'command'}->[-1];
|
|
$self->{'file'} = $self->{'_iterator'}->{'command'}->[-1];
|
|
|
print "PROCESSING RESULTS FROM TEST FILE: $self->{'file'}\n";
|
|
print "PROCESSING RESULTS FROM TEST FILE: $self->{'file'}\n";
|
|
|
|
|
+ $self->{'track_time'} = 1;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ #Not running inside of prove in real-time, don't bother with tracking elapsed times.
|
|
|
|
|
+ $self->{'track_time'} = 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#Make sure the step results field passed exists on the system
|
|
#Make sure the step results field passed exists on the system
|
|
@@ -188,6 +195,8 @@ sub new {
|
|
|
|
|
|
|
|
$self->{'tr_opts'} = $tropts;
|
|
$self->{'tr_opts'} = $tropts;
|
|
|
$self->{'errors'} = 0;
|
|
$self->{'errors'} = 0;
|
|
|
|
|
+ #Start the shot clock
|
|
|
|
|
+ $self->{'starttime'} = time();
|
|
|
|
|
|
|
|
return $self;
|
|
return $self;
|
|
|
}
|
|
}
|
|
@@ -258,6 +267,11 @@ sub testCallback {
|
|
|
my $test = $args[0];
|
|
my $test = $args[0];
|
|
|
our $self;
|
|
our $self;
|
|
|
|
|
|
|
|
|
|
+ if ( $self->{'track_time'} ) {
|
|
|
|
|
+ #Test done. Record elapsed time.
|
|
|
|
|
+ $self->{'tr_opts'}->{'result_options'}->{'elapsed'} = _compute_elapsed($self->{'starttime'},time());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
#Don't do anything if we don't want to map TR case => ok or use step-by-step results
|
|
#Don't do anything if we don't want to map TR case => ok or use step-by-step results
|
|
|
if ( !($self->{'tr_opts'}->{'step_results'} || $self->{'tr_opts'}->{'case_per_ok'}) ) {
|
|
if ( !($self->{'tr_opts'}->{'step_results'} || $self->{'tr_opts'}->{'case_per_ok'}) ) {
|
|
|
print "Neither step_results of case_per_ok set. No action to be taken, except on a whole test basis.\n" if $self->{'tr_opts'}->{'debug'};
|
|
print "Neither step_results of case_per_ok set. No action to be taken, except on a whole test basis.\n" if $self->{'tr_opts'}->{'debug'};
|
|
@@ -332,6 +346,8 @@ sub testCallback {
|
|
|
my $custom_options = $self->{'tr_opts'}->{'result_custom_options'};
|
|
my $custom_options = $self->{'tr_opts'}->{'result_custom_options'};
|
|
|
|
|
|
|
|
_set_result($run_id,$test_name,$status,$notes,$options,$custom_options);
|
|
_set_result($run_id,$test_name,$status,$notes,$options,$custom_options);
|
|
|
|
|
+ #Re-start the shot clock
|
|
|
|
|
+ $self->{'starttime'} = time();
|
|
|
|
|
|
|
|
#Blank out test description in anticipation of next test
|
|
#Blank out test description in anticipation of next test
|
|
|
# also blank out notes
|
|
# also blank out notes
|
|
@@ -350,9 +366,14 @@ Otherwise, upload the overall results of the test to TestRail.
|
|
|
sub EOFCallback {
|
|
sub EOFCallback {
|
|
|
our $self;
|
|
our $self;
|
|
|
|
|
|
|
|
|
|
+ if ( $self->{'track_time'} ) {
|
|
|
|
|
+ #Test done. Record elapsed time.
|
|
|
|
|
+ $self->{'tr_opts'}->{'result_options'}->{'elapsed'} = _compute_elapsed($self->{'starttime'},time());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (!(!$self->{'tr_opts'}->{'step_results'} xor $self->{'tr_opts'}->{'case_per_ok'})) {
|
|
if (!(!$self->{'tr_opts'}->{'step_results'} xor $self->{'tr_opts'}->{'case_per_ok'})) {
|
|
|
print "Nothing left to do.\n";
|
|
print "Nothing left to do.\n";
|
|
|
- undef $self->{'tr_opts'};
|
|
|
|
|
|
|
+ undef $self->{'tr_opts'} unless $self->{'tr_opts'}->{'debug'};
|
|
|
return 1;
|
|
return 1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -379,7 +400,7 @@ sub EOFCallback {
|
|
|
print "Setting results...\n";
|
|
print "Setting results...\n";
|
|
|
my $cres = _set_result($run_id,$test_name,$status,$notes,$options,$custom_options);
|
|
my $cres = _set_result($run_id,$test_name,$status,$notes,$options,$custom_options);
|
|
|
|
|
|
|
|
- undef $self->{'tr_opts'};
|
|
|
|
|
|
|
+ undef $self->{'tr_opts'} unless $self->{'tr_opts'}->{'debug'};
|
|
|
|
|
|
|
|
return $cres;
|
|
return $cres;
|
|
|
}
|
|
}
|
|
@@ -389,6 +410,8 @@ sub _set_result {
|
|
|
our $self;
|
|
our $self;
|
|
|
my $tc;
|
|
my $tc;
|
|
|
|
|
|
|
|
|
|
+ print "Test elapsed: ".$options->{'elapsed'}."\n" if $options->{'elapsed'};
|
|
|
|
|
+
|
|
|
print "Attempting to find case by title '".$test_name."'...\n";
|
|
print "Attempting to find case by title '".$test_name."'...\n";
|
|
|
$tc = $self->{'tr_opts'}->{'testrail'}->getTestByName($run_id,$test_name);
|
|
$tc = $self->{'tr_opts'}->{'testrail'}->getTestByName($run_id,$test_name);
|
|
|
if (!defined($tc) || (reftype($tc) || 'undef') ne 'HASH') {
|
|
if (!defined($tc) || (reftype($tc) || 'undef') ne 'HASH') {
|
|
@@ -415,6 +438,32 @@ sub _set_result {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#Compute the expected testrail date interval from 2 unix timestamps.
|
|
|
|
|
+sub _compute_elapsed {
|
|
|
|
|
+ my ($begin,$end) = @_;
|
|
|
|
|
+ my $secs_elapsed = $end - $begin;
|
|
|
|
|
+ my $mins_elapsed = floor($secs_elapsed / 60);
|
|
|
|
|
+ my $secs_remain = $secs_elapsed % 60;
|
|
|
|
|
+ my $hours_elapsed = floor($mins_elapsed / 60);
|
|
|
|
|
+ my $mins_remain = $mins_elapsed % 60;
|
|
|
|
|
+
|
|
|
|
|
+ my $datestr = "";
|
|
|
|
|
+
|
|
|
|
|
+ #You have bigger problems if your test takes days
|
|
|
|
|
+ if ($hours_elapsed) {
|
|
|
|
|
+ $datestr .= "$hours_elapsed"."h $mins_remain"."m";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $datestr .= "$mins_elapsed"."m";
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($mins_elapsed) {
|
|
|
|
|
+ $datestr .= " $secs_remain"."s";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $datestr .= " $secs_elapsed"."s";
|
|
|
|
|
+ }
|
|
|
|
|
+ undef $datestr if $datestr eq "0m 0s";
|
|
|
|
|
+ return $datestr;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
1;
|
|
1;
|
|
|
|
|
|
|
|
__END__
|
|
__END__
|