Browse Source

Fix #52: Add --autoclose feature

George S. Baugh 10 years ago
parent
commit
78fcb4f310

+ 2 - 0
Changes

@@ -7,6 +7,8 @@ Revision history for Perl module TestRail::API
     - Fix issue where specifying sections past the first defined in a project would fail to restrict spawning to said sections
     - Fix issue where specifying sections past the first defined in a project would fail to restrict spawning to said sections
     - Add Plan Summarizer function
     - Add Plan Summarizer function
     - Always append the full raw TAP to all results
     - Always append the full raw TAP to all results
+    - Add closePlan and closeRun functions to TestRail::API
+    - Add option to binaries, plugin to close plan/run if no untested/retest exist at end of TAP parse
 
 
 0.026 2015-06-06 TEODESIAN
 0.026 2015-06-06 TEODESIAN
     - Add --no-match option to testrail-tests to find orphan tests in a tree
     - Add --no-match option to testrail-tests to find orphan tests in a tree

+ 7 - 2
bin/testrail-report

@@ -77,7 +77,8 @@ overall result of the test will be used as the pass/fail for the test.
 
 
 =head3 RESULT OPTIONS
 =head3 RESULT OPTIONS
 
 
-    --version : String describing the version of the system under test.
+    --version   : String describing the version of the system under test.
+    --autoclose : If there are no more tests in 'untested' or 'retest' status for the specified run/plan, close it.
 
 
 =head2 PROVE PLUGIN:
 =head2 PROVE PLUGIN:
 
 
@@ -203,6 +204,8 @@ PARAMETERS:
   [RESULT OPTIONS]
   [RESULT OPTIONS]
 
 
     --version : String describing the version of the system under test.
     --version : String describing the version of the system under test.
+    --autoclose : If there are no more tests in 'untested' or 'retest'
+                  status for the specified run/plan, close it.
 
 
 PROVE PLUGIN:
 PROVE PLUGIN:
 
 
@@ -227,7 +230,7 @@ TESTING OPTIONS:
 
 
 #Main loop------------
 #Main loop------------
 
 
-my ($help,$apiurl,$user,$password,$project,$run,$case_per_ok,$step_results,$mock,$configs,$plan,$version,$spawn,$sections);
+my ($help,$apiurl,$user,$password,$project,$run,$case_per_ok,$step_results,$mock,$configs,$plan,$version,$spawn,$sections,$autoclose);
 
 
 #parse switches
 #parse switches
 GetOptions(
 GetOptions(
@@ -244,6 +247,7 @@ GetOptions(
     'version=s'      => \$version,
     'version=s'      => \$version,
     'spawn=i'        => \$spawn,
     'spawn=i'        => \$spawn,
     'section=s@'     => \$sections,
     'section=s@'     => \$sections,
+    'autoclose'      => \$autoclose,
     'help'           => \$help
     'help'           => \$help
 );
 );
 
 
@@ -364,6 +368,7 @@ foreach my $phil (@files) {
         'result_options' => $result_options,
         'result_options' => $result_options,
         'spawn'        => $spawn,
         'spawn'        => $spawn,
         'sections'     => $sections,
         'sections'     => $sections,
+        'autoclose'    => $autoclose,
         'merge'        => 1
         'merge'        => 1
     });
     });
     $tap->run();
     $tap->run();

+ 3 - 0
dist.ini

@@ -109,6 +109,9 @@ stopwords = getPlansPaginated
 stopwords = getRunsPaginated
 stopwords = getRunsPaginated
 stopwords = getPossibleTestStatuses
 stopwords = getPossibleTestStatuses
 stopwords = userInput
 stopwords = userInput
+stopwords = autoclose
+stopwords = closeRun
+stopwords = closePlan
 
 
 [PkgVersion]
 [PkgVersion]
 [AutoPrereqs]
 [AutoPrereqs]

+ 14 - 12
lib/App/Prove/Plugin/TestRail.pm

@@ -36,6 +36,7 @@ If \$HOME/.testrailrc exists, it will be parsed for any of these values in a new
     step_results=sr_sys_name
     step_results=sr_sys_name
     spawn=123
     spawn=123
     sections=section1:section2:section3: ... :sectionN
     sections=section1:section2:section3: ... :sectionN
+    autoclose=0
 
 
 Note that passing configurations as filters for runs inside of plans are separated by colons.
 Note that passing configurations as filters for runs inside of plans are separated by colons.
 Values passed in via query string will override values in \$HOME/.testrailrc.
 Values passed in via query string will override values in \$HOME/.testrailrc.
@@ -81,18 +82,19 @@ sub load {
     $app->merge(1);
     $app->merge(1);
 
 
     #XXX I can't figure out for the life of me any other way to pass this data. #YOLO
     #XXX I can't figure out for the life of me any other way to pass this data. #YOLO
-    $ENV{'TESTRAIL_APIURL'}   = $params->{apiurl};
-    $ENV{'TESTRAIL_USER'}     = $params->{user};
-    $ENV{'TESTRAIL_PASS'}     = $params->{password};
-    $ENV{'TESTRAIL_PROJ'}     = $params->{project};
-    $ENV{'TESTRAIL_RUN'}      = $params->{run};
-    $ENV{'TESTRAIL_PLAN'}     = $params->{plan};
-    $ENV{'TESTRAIL_CONFIGS'}  = $params->{configs};
-    $ENV{'TESTRAIL_VERSION'}  = $params->{version};
-    $ENV{'TESTRAIL_CASEOK'}   = $params->{case_per_ok};
-    $ENV{'TESTRAIL_STEPS'}    = $params->{step_results};
-    $ENV{'TESTRAIL_SPAWN'}    = $params->{spawn};
-    $ENV{'TESTRAIL_SECTIONS'} = $params->{sections};
+    $ENV{'TESTRAIL_APIURL'}    = $params->{apiurl};
+    $ENV{'TESTRAIL_USER'}      = $params->{user};
+    $ENV{'TESTRAIL_PASS'}      = $params->{password};
+    $ENV{'TESTRAIL_PROJ'}      = $params->{project};
+    $ENV{'TESTRAIL_RUN'}       = $params->{run};
+    $ENV{'TESTRAIL_PLAN'}      = $params->{plan};
+    $ENV{'TESTRAIL_CONFIGS'}   = $params->{configs};
+    $ENV{'TESTRAIL_VERSION'}   = $params->{version};
+    $ENV{'TESTRAIL_CASEOK'}    = $params->{case_per_ok};
+    $ENV{'TESTRAIL_STEPS'}     = $params->{step_results};
+    $ENV{'TESTRAIL_SPAWN'}     = $params->{spawn};
+    $ENV{'TESTRAIL_SECTIONS'}  = $params->{sections};
+    $ENV{'TESTRAIL_AUTOCLOSE'} = $params->{autoclose};
     return $class;
     return $class;
 }
 }
 
 

File diff suppressed because it is too large
+ 215 - 3
lib/Test/LWP/UserAgent/TestRailMock.pm


+ 5 - 2
lib/Test/Rail/Harness.pm

@@ -49,14 +49,17 @@ sub make_parser {
     $args->{'project'} = $ENV{'TESTRAIL_PROJ'};
     $args->{'project'} = $ENV{'TESTRAIL_PROJ'};
     $args->{'run'}     = $ENV{'TESTRAIL_RUN'};
     $args->{'run'}     = $ENV{'TESTRAIL_RUN'};
     $args->{'plan'}    = $ENV{'TESTRAIL_PLAN'};
     $args->{'plan'}    = $ENV{'TESTRAIL_PLAN'};
+    
     @configs = split(/:/,$ENV{'TESTRAIL_CONFIGS'}) if $ENV{'TESTRAIL_CONFIGS'};
     @configs = split(/:/,$ENV{'TESTRAIL_CONFIGS'}) if $ENV{'TESTRAIL_CONFIGS'};
-    $args->{'configs'} = \@configs if scalar(@configs);
+    $args->{'configs'}        = \@configs if scalar(@configs);
     $args->{'result_options'} = {'version' => $ENV{'TESTRAIL_VERSION'}} if $ENV{'TESTRAIL_VERSION'};
     $args->{'result_options'} = {'version' => $ENV{'TESTRAIL_VERSION'}} if $ENV{'TESTRAIL_VERSION'};
     $args->{'case_per_ok'}    = $ENV{'TESTRAIL_CASEOK'};
     $args->{'case_per_ok'}    = $ENV{'TESTRAIL_CASEOK'};
     $args->{'step_results'}   = $ENV{'TESTRAIL_STEPS'};
     $args->{'step_results'}   = $ENV{'TESTRAIL_STEPS'};
     $args->{'spawn'}          = $ENV{'TESTRAIL_SPAWN'};
     $args->{'spawn'}          = $ENV{'TESTRAIL_SPAWN'};
+    
     @sections = split(/:/,$ENV{'TESTRAIL_SECTIONS'}) if $ENV{'TESTRAIL_SECTIONS'};
     @sections = split(/:/,$ENV{'TESTRAIL_SECTIONS'}) if $ENV{'TESTRAIL_SECTIONS'};
-    $args->{'sections'} = \@sections if scalar(@sections);
+    $args->{'sections'}  = \@sections if scalar(@sections);
+    $args->{'autoclose'} = $ENV{'TESTRAIL_AUTOCLOSE'};
 
 
     #for Testability of plugin
     #for Testability of plugin
     if ($ENV{'TESTRAIL_MOCKED'}) {
     if ($ENV{'TESTRAIL_MOCKED'}) {

+ 27 - 1
lib/Test/Rail/Parser.pm

@@ -76,6 +76,8 @@ Get the TAP Parser ready to talk to TestRail, and register a bunch of callbacks
 
 
 =item B<sections> - ARRAYREF (optional): Restrict a spawned run to cases in these particular sections.
 =item B<sections> - ARRAYREF (optional): Restrict a spawned run to cases in these particular sections.
 
 
+=item B<autoclose> - BOOLEAN (optional): If no cases in the run/plan are marked 'untested' or 'retest', go ahead and close the run.  Default false.
+
 =back
 =back
 
 
 =back
 =back
@@ -128,6 +130,7 @@ sub new {
         'configs'      => delete $opts->{'configs'} // [],
         'configs'      => delete $opts->{'configs'} // [],
         'spawn'        => delete $opts->{'spawn'},
         'spawn'        => delete $opts->{'spawn'},
         'sections'     => delete $opts->{'sections'},
         'sections'     => delete $opts->{'sections'},
+        'autoclose'    => delete $opts->{'autoclose'},
         #Stubs for extension by subclassers
         #Stubs for extension by subclassers
         'result_options'        => delete $opts->{'result_options'},
         'result_options'        => delete $opts->{'result_options'},
         'result_custom_options' => delete $opts->{'result_custom_options'}
         'result_custom_options' => delete $opts->{'result_custom_options'}
@@ -253,7 +256,6 @@ sub new {
         confess("Could not spawn run with requested parameters!") if !$tropts->{'run_id'};
         confess("Could not spawn run with requested parameters!") if !$tropts->{'run_id'};
         print "# Success!\n"
         print "# Success!\n"
     }
     }
-
     confess("No run ID provided, and no run with specified name exists in provided project/plan!") if !$tropts->{'run_id'};
     confess("No run ID provided, and no run with specified name exists in provided project/plan!") if !$tropts->{'run_id'};
 
 
     $self = $class->SUPER::new($opts);
     $self = $class->SUPER::new($opts);
@@ -454,6 +456,7 @@ sub EOFCallback {
 
 
     if ($self->{'tr_opts'}->{'case_per_ok'}) {
     if ($self->{'tr_opts'}->{'case_per_ok'}) {
         print "# Nothing left to do.\n";
         print "# Nothing left to do.\n";
+        $self->_test_closure();
         undef $self->{'tr_opts'} unless $self->{'tr_opts'}->{'debug'};
         undef $self->{'tr_opts'} unless $self->{'tr_opts'}->{'debug'};
         return 1;
         return 1;
     }
     }
@@ -483,6 +486,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);
+    $self->_test_closure();
     $self->{'global_status'} = $status;
     $self->{'global_status'} = $status;
 
 
     undef $self->{'tr_opts'} unless $self->{'tr_opts'}->{'debug'};
     undef $self->{'tr_opts'} unless $self->{'tr_opts'}->{'debug'};
@@ -550,6 +554,28 @@ sub _compute_elapsed {
     return $datestr;
     return $datestr;
 }
 }
 
 
+sub _test_closure {
+    my ($self) = @_;
+    return unless $self->{'tr_opts'}->{'autoclose'};
+    my $is_plan = $self->{'tr_opts'}->{'plan'} ? 1 : 0;
+    my $id      = $self->{'tr_opts'}->{'plan'} ? $self->{'tr_opts'}->{'plan'}->{'id'} : $self->{'tr_opts'}->{'run'};
+  
+    if ($is_plan) {
+        my $plan_summary = $self->{'tr_opts'}->{'testrail'}->getPlanSummary($id);
+
+        return if ( $plan_summary->{'totals'}->{'untested'} + $plan_summary->{'totals'}->{'retest'} );
+        print "# No more outstanding cases detected.  Closing Plan.\n";
+        $self->{'plan_closed'} = 1;
+        return $self->{'tr_opts'}->{'testrail'}->closePlan($id);
+    }
+
+    my ($run_summary) = $self->{'tr_opts'}->{'testrail'}->getRunSummary($id);
+    return if ( $run_summary->{'run_status'}->{'untested'} + $run_summary->{'run_status'}->{'retest'} );
+    print "# No more outstanding cases detected.  Closing Run.\n";
+    $self->{'run_closed'} = 1;
+    return $self->{'tr_opts'}->{'testrail'}->closeRun($self->{'tr_opts'}->{'run_id'});
+}
+
 1;
 1;
 
 
 __END__
 __END__

+ 51 - 1
lib/TestRail/API.pm

@@ -1217,6 +1217,29 @@ sub getRunByID {
     return $self->_doRequest("index.php?/api/v2/get_run/$run_id");
     return $self->_doRequest("index.php?/api/v2/get_run/$run_id");
 }
 }
 
 
+=head2 B<closeRun (run_id)>
+
+Close the specified run.
+
+=over 4
+
+=item INTEGER C<RUN ID> - ID of desired run.
+
+=back
+
+Returns run definition HASHREF on success, false on failure.
+
+    $tr->closeRun(90210);
+
+=cut
+
+sub closeRun {
+    my ($self,$run_id) = @_;
+    confess("Object methods must be called by an instance") unless ref($self);
+    confess("Run ID must be integer") unless $self->_checkInteger($run_id);
+    return $self->_doRequest("index.php?/api/v2/close_run/$run_id",'POST');
+}
+
 =head2 B<getRunSummary(runs)>
 =head2 B<getRunSummary(runs)>
 
 
 Returns array of hashrefs describing the # of tests in the run(s) with the available statuses.
 Returns array of hashrefs describing the # of tests in the run(s) with the available statuses.
@@ -1236,6 +1259,8 @@ Returns ARRAY of run HASHREFs with the added key 'run_status' holding a hashref
 
 
 sub getRunSummary {
 sub getRunSummary {
     my ($self,@runs) = @_;
     my ($self,@runs) = @_;
+    confess("Object methods must be called by an instance") unless ref($self);
+    confess("All Plans passed must be HASHREFs") unless scalar( grep {(reftype($_) || 'undef') eq 'HASH'} @runs ) == scalar(@runs);
 
 
     #Translate custom statuses
     #Translate custom statuses
     my $statuses = $self->getPossibleTestStatuses();
     my $statuses = $self->getPossibleTestStatuses();
@@ -1548,6 +1573,8 @@ sub getPlanByID {
 =head2 B<getPlanSummary(plan_ID)>
 =head2 B<getPlanSummary(plan_ID)>
 
 
 Returns hashref describing the various pass, fail, etc. percentages for tests in the plan.
 Returns hashref describing the various pass, fail, etc. percentages for tests in the plan.
+The 'totals' key has total cases in each status ('status' => count)
+The 'percentages' key has the same, but as a percentage of the total.
 
 
 =over 4
 =over 4
 
 
@@ -1590,7 +1617,7 @@ sub getPlanSummary {
 
 
 =head2 B<createRunInPlan (plan_id,suite_id,name,description,milestone_id,assigned_to_id,config_ids,case_ids)>
 =head2 B<createRunInPlan (plan_id,suite_id,name,description,milestone_id,assigned_to_id,config_ids,case_ids)>
 
 
-Create a run.
+Create a run in a plan.
 
 
 =over 4
 =over 4
 
 
@@ -1646,6 +1673,29 @@ sub createRunInPlan {
     return $result;
     return $result;
 }
 }
 
 
+=head2 B<closePlan (plan_id)>
+
+Close the specified plan.
+
+=over 4
+
+=item INTEGER C<PLAN ID> - ID of desired plan.
+
+=back
+
+Returns plan definition HASHREF on success, false on failure.
+
+    $tr->closePlan(75020);
+
+=cut
+
+sub closePlan {
+    my ($self,$plan_id) = @_;
+    confess("Object methods must be called by an instance") unless ref($self);
+    confess("Plan ID must be integer") unless $self->_checkInteger($plan_id);
+    return $self->_doRequest("index.php?/api/v2/close_plan/$plan_id",'POST');
+}
+
 =head1 MILESTONE METHODS
 =head1 MILESTONE METHODS
 
 
 =head2 B<createMilestone (project_id,name,description,due_on)>
 =head2 B<createMilestone (project_id,name,description,due_on)>

+ 6 - 1
t/App-Prove-Plugin-Testrail.t

@@ -3,7 +3,7 @@
 use strict;
 use strict;
 use warnings;
 use warnings;
 
 
-use Test::More 'tests' => 5;
+use Test::More 'tests' => 6;
 use Test::Fatal;
 use Test::Fatal;
 use App::Prove;
 use App::Prove;
 use App::Prove::Plugin::TestRail;
 use App::Prove::Plugin::TestRail;
@@ -39,3 +39,8 @@ $prove = App::Prove->new();
 $prove->process_args("-PTestRail=apiurl=http://some.testlink.install/,user=someUser,password=somePassword,project=TestProject,run=bogoRun,version=0.014,case_per_ok=1,spawn=9,sections=fake.test:CARBON LIQUEFACTION",'t/fake.test');
 $prove->process_args("-PTestRail=apiurl=http://some.testlink.install/,user=someUser,password=somePassword,project=TestProject,run=bogoRun,version=0.014,case_per_ok=1,spawn=9,sections=fake.test:CARBON LIQUEFACTION",'t/fake.test');
 
 
 is (exception {$prove->run()},undef,"Running TR parser can discriminate by sections correctly");
 is (exception {$prove->run()},undef,"Running TR parser can discriminate by sections correctly");
+
+$prove = App::Prove->new();
+$prove->process_args("-PTestRail=apiurl=http://some.testlink.install/,user=someUser,password=somePassword,project=TestProject,plan=FinalPlan,run=FinalRun,configs=testConfig,version=0.014,case_per_ok=1,autoclose=1",'t/fake.test');
+
+is (exception {$prove->run()},undef,"Running TR parser with autoclose works correctly");

+ 108 - 2
t/Test-Rail-Parser.t

@@ -7,7 +7,7 @@ use Scalar::Util qw{reftype};
 use TestRail::API;
 use TestRail::API;
 use Test::LWP::UserAgent::TestRailMock;
 use Test::LWP::UserAgent::TestRailMock;
 use Test::Rail::Parser;
 use Test::Rail::Parser;
-use Test::More 'tests' => 62;
+use Test::More 'tests' => 78;
 use Test::Fatal qw{exception};
 use Test::Fatal qw{exception};
 
 
 #Same song and dance as in TestRail-API.t
 #Same song and dance as in TestRail-API.t
@@ -521,5 +521,111 @@ if (!$res) {
     is($tap->{'global_status'},8, "Test global result is TODO PASS on todo pass test");
     is($tap->{'global_status'},8, "Test global result is TODO PASS on todo pass test");
 }
 }
 
 
+#Check autoclose functionality against Run with all tests in run status.
+undef $tap;
+$res = exception {
+    $tap = Test::Rail::Parser->new({
+        'source'              => 't/skip.test',
+        'apiurl'              => $apiurl,
+        'user'                => $login,
+        'pass'                => $pw,
+        'debug'               => $debug,
+        'browser'             => $browser,
+        'run'                 => 'FinalRun',
+        'project'             => 'TestProject',
+        'merge'               => 1,
+        'autoclose'           => 1,
+        'spawn'               => 9,
+    });
+};
+is($res,undef,"TR Parser doesn't explode on instantiation");
+isa_ok($tap,"Test::Rail::Parser");
+
+if (!$res) {
+    $tap->run();
+    is($tap->{'errors'},0,"No errors encountered uploading case results");
+    is($tap->{'run_closed'},1, "Run closed by parser when all tests done");
+}
+
+#Check autoclose functionality against Run with not all tests in run status.
+undef $tap;
+$res = exception {
+    $tap = Test::Rail::Parser->new({
+        'source'              => 't/todo_pass.test',
+        'apiurl'              => $apiurl,
+        'user'                => $login,
+        'pass'                => $pw,
+        'debug'               => $debug,
+        'browser'             => $browser,
+        'run'                 => 'BogoRun',
+        'project'             => 'TestProject',
+        'merge'               => 1,
+        'autoclose'           => 1,
+        'spawn'               => 9,
+    });
+};
+is($res,undef,"TR Parser doesn't explode on instantiation");
+isa_ok($tap,"Test::Rail::Parser");
+
+if (!$res) {
+    $tap->run();
+    is($tap->{'errors'},0,"No errors encountered uploading case results");
+    is($tap->{'run_closed'},undef, "Run not closed by parser when results are outstanding");
+}
+
+#Check that autoclose works against plan wiht all tests in run status
+undef $tap;
+$res = exception {
+    $tap = Test::Rail::Parser->new({
+        'source'              => 't/fake.test',
+        'apiurl'              => $apiurl,
+        'user'                => $login,
+        'pass'                => $pw,
+        'debug'               => $debug,
+        'browser'             => $browser,
+        'run'                 => 'FinalRun',
+        'plan'                => 'FinalPlan',
+        'project'             => 'TestProject',
+        'configs'             => ['testConfig'],
+        'merge'               => 1,
+        'autoclose'           => 1,
+        'case_per_ok'         => 1
+    });
+};
+is($res,undef,"TR Parser doesn't explode on instantiation");
+isa_ok($tap,"Test::Rail::Parser");
+
+if (!$res) {
+    $tap->run();
+    is($tap->{'errors'},0,"No errors encountered uploading case results");
+    is($tap->{'plan_closed'},1, "Plan closed by parser when all tests done");
+}
+
+#Check that autoclose works against plan wiht all tests not in run status
+undef $tap;
+$res = exception {
+    $tap = Test::Rail::Parser->new({
+        'source'              => 't/fake.test',
+        'apiurl'              => $apiurl,
+        'user'                => $login,
+        'pass'                => $pw,
+        'debug'               => $debug,
+        'browser'             => $browser,
+        'run'                 => 'BogoRun',
+        'plan'                => 'BogoPlan',
+        'project'             => 'TestProject',
+        'spawn'               => 9,
+        'merge'               => 1,
+        'autoclose'           => 1,
+        'case_per_ok'         => 1
+    });
+};
+is($res,undef,"TR Parser doesn't explode on instantiation");
+isa_ok($tap,"Test::Rail::Parser");
+
+if (!$res) {
+    $tap->run();
+    is($tap->{'errors'},0,"No errors encountered uploading case results");
+    is($tap->{'plan_closed'},undef, "Plan not closed by parser when results are outstanding");
+}
 
 
-0;

+ 7 - 1
t/TestRail-API-mockOnly.t

@@ -3,7 +3,7 @@ use warnings;
 
 
 #Test things we can only mock, because the API doesn't support them.
 #Test things we can only mock, because the API doesn't support them.
 
 
-use Test::More 'tests' => 9;
+use Test::More 'tests' => 13;
 use TestRail::API;
 use TestRail::API;
 use Test::LWP::UserAgent::TestRailMock;
 use Test::LWP::UserAgent::TestRailMock;
 use Scalar::Util qw{reftype};
 use Scalar::Util qw{reftype};
@@ -34,3 +34,9 @@ $projResType = $tr->getTestResultFieldByName('moo_results');
 is($projResType,0,"Bad name returns no result field");
 is($projResType,0,"Bad name returns no result field");
 $projResType = $tr->getTestResultFieldByName('step_results',66669);
 $projResType = $tr->getTestResultFieldByName('step_results',66669);
 is($projResType,-3,"Bad project returns no result field");
 is($projResType,-3,"Bad project returns no result field");
+
+# I can't delete closed plans, so...test closePlan et cetera
+is(reftype($tr->closeRun(666)),'HASH',"Can close run that exists");
+is($tr->closeRun(90210),-404,"Can't close run that doesn't exist");
+is(reftype($tr->closePlan(23)),'HASH',"Can close plan that exists");
+is($tr->closePlan(75020),-404,"Can't close plan that doesn't exist");

+ 3 - 1
t/arg_types.t

@@ -2,7 +2,7 @@ use strict;
 use warnings;
 use warnings;
 
 
 use TestRail::API;
 use TestRail::API;
-use Test::More 'tests' => 139;
+use Test::More 'tests' => 141;
 use Test::Fatal;
 use Test::Fatal;
 use Class::Inspector;
 use Class::Inspector;
 use Test::LWP::UserAgent;
 use Test::LWP::UserAgent;
@@ -74,6 +74,8 @@ isnt( exception {$tr->createRunInPlan() },undef,'createRunInPlan returns error w
 isnt( exception {$tr->translateConfigNamesToIds()}, undef,'translateConfigNamesToIds returns error when no arguments are passed');
 isnt( exception {$tr->translateConfigNamesToIds()}, undef,'translateConfigNamesToIds returns error when no arguments are passed');
 isnt( exception {$tr->userNamesToIds()}, undef,'userNamesToIds returns error when no arguments are passed');
 isnt( exception {$tr->userNamesToIds()}, undef,'userNamesToIds returns error when no arguments are passed');
 isnt( exception {$tr->statusNamesToIds()}, undef,'statusNamesToIds returns error when no arguments are passed');
 isnt( exception {$tr->statusNamesToIds()}, undef,'statusNamesToIds returns error when no arguments are passed');
+isnt( exception {$tr->getRunSummary()}, undef,'getRunSummary returns error when no arguments are passed');
+isnt( exception {$tr->getPlanSummary()}, undef,'getPlanSummary returns error when no arguments are passed');
 
 
 #1-arg functions
 #1-arg functions
 is(exception {$tr->deleteCase(1)},            undef,'deleteCase returns no error when int arg passed');
 is(exception {$tr->deleteCase(1)},            undef,'deleteCase returns no error when int arg passed');

+ 19 - 0
t/fake.tap

@@ -0,0 +1,19 @@
+t/fake.test ..
+1..2
+ok 1 - STORAGE TANKS SEARED
+# whee
+not ok 2 - NOT SO SEARED AFTER ARR
+
+#   Failed test 'NOT SO SEARED AFTER ARR'
+#   at t/fake.test line 10.
+# Looks like you failed 1 test of 2.
+Dubious, test returned 1 (wstat 256, 0x100)
+Failed 1/2 subtests
+
+Test Summary Report
+-------------------
+t/fake.test (Wstat: 256 Tests: 2 Failed: 1)
+  Failed test:  2
+  Non-zero exit status: 1
+Files=1, Tests=2,  2 wallclock secs ( 0.02 usr  0.00 sys +  0.01 cusr  0.00 csys =  0.03 CPU)
+Result: FAIL

+ 7 - 1
t/testrail-report.t

@@ -1,7 +1,7 @@
 use strict;
 use strict;
 use warnings;
 use warnings;
 
 
-use Test::More 'tests' => 14;
+use Test::More 'tests' => 16;
 
 
 my @args = ($^X,qw{bin/testrail-report --apiurl http://testrail.local --user "test@fake.fake" --password "fake" --project "CRUSH ALL HUMANS" --run "SEND T-1000 INFILTRATION UNITS BACK IN TIME" --mock t/test_multiple_files.tap});
 my @args = ($^X,qw{bin/testrail-report --apiurl http://testrail.local --user "test@fake.fake" --password "fake" --project "CRUSH ALL HUMANS" --run "SEND T-1000 INFILTRATION UNITS BACK IN TIME" --mock t/test_multiple_files.tap});
 my $out = `@args`;
 my $out = `@args`;
@@ -43,6 +43,12 @@ is($? >> 8, 0, "Exit code OK reported with spawn");
 $matches = () = $out =~ m/with specified sections/ig;
 $matches = () = $out =~ m/with specified sections/ig;
 is($matches,1,"Attempts to spawn work");
 is($matches,1,"Attempts to spawn work");
 
 
+#Test that the autoclose option works
+@args = ($^X,qw{bin/testrail-report --apiurl http://testrail.local --user "test@fake.fake" --password "fake" --project "TestProject" --run "FinalRun" --plan "FinalPlan" --config "testConfig" --case-ok --autoclose --mock t/fake.tap});
+$out = `@args`;
+is($? >> 8, 0, "Exit code OK when doing autoclose");
+like($out,qr/closing plan/i,"Run closure reported to user");
+
 #Test that help works
 #Test that help works
 @args = ($^X,qw{bin/testrail-report --help});
 @args = ($^X,qw{bin/testrail-report --help});
 $out = `@args`;
 $out = `@args`;

+ 1 - 1
t/testrail-runs.t

@@ -8,7 +8,7 @@ my @args = ($^X,qw{bin/testrail-runs --apiurl http://testrail.local --user "test
 my $out = `@args`;
 my $out = `@args`;
 is($? >> 8, 0, "Exit code OK looking for runs with passes");
 is($? >> 8, 0, "Exit code OK looking for runs with passes");
 chomp $out;
 chomp $out;
-like($out,qr/^TestingSuite\nOtherOtherSuite$/,"Gets run correctly looking for passes");
+like($out,qr/^TestingSuite\nOtherOtherSuite\nFinalRun$/,"Gets run correctly looking for passes");
 
 
 #check status filters
 #check status filters
 @args = ($^X,qw{bin/testrail-runs --apiurl http://testrail.local --user "test@fake.fake" --password "fake" -j "TestProject" --mock --status passed});
 @args = ($^X,qw{bin/testrail-runs --apiurl http://testrail.local --user "test@fake.fake" --password "fake" -j "TestProject" --mock --status passed});

Some files were not shown because too many files changed in this diff