Browse Source

v12 release. Fixed issues with dzil tests, etc.

George S. Baugh 11 years ago
parent
commit
81e9ca29e2

+ 1 - 1
Changes

@@ -1,6 +1,6 @@
 Revision history for Perl module TestRail::API
 Revision history for Perl module TestRail::API
 
 
-0.012 2014-12-?? TEODESIAN
+0.012 2014-12-30 TEODESIAN
     - DZIL tidying
     - DZIL tidying
     - Re-enabled some of the critic tests, fixed a few related issues
     - Re-enabled some of the critic tests, fixed a few related issues
     - Improve safety of constructor, try to die with helpful messages as soon as possible
     - Improve safety of constructor, try to die with helpful messages as soon as possible

+ 85 - 3
bin/testrail-report

@@ -2,12 +2,79 @@
 # ABSTRACT: Upload your TAP results to TestRail after they've finished
 # ABSTRACT: Upload your TAP results to TestRail after they've finished
 # PODNAME: testrail-report
 # PODNAME: testrail-report
 
 
+=head1 SYNOPSIS
+
+  testrail-report [OPTIONS] tapfile
+  prove -v sometest.t > results.tap && testrail-report [OPTIONS] results.tap
+
+  prove -v sometest.t | testrail-report [OPTIONS]
+
+  prove -PTestRail='http://some.testlink.install/,someUser,somePassword,someProject,someRun,0,step_results' sometest.t
+
+=head1 DESCRIPTION
+
+testrail-report - report raw TAP results to a TestRail install
+
+USAGE:
+=head2 PARAMETERS:
+
+=head3 MANDATORY PARAMETERS
+
+    --project [someproject] : associate results (if any) with theprovided project name.
+
+    --run [somerun] : associates results (if any) with the provided run name.
+
+IF none of these options are provided, you will be asked to type
+these in as needed, supposing you are not redirecting input
+(such as piping into this command).
+
+=head3 CONFIG OVERRIDES
+
+In your \$HOME, put a file called .testrailrc with key=value
+syntax separated by newlines.  Valid Keys are: apiurl,user,password
+
+=head3 CONFIG OPTIONS
+
+These override the config, if present.  If neither are used, you will be prompted.
+
+    --apiurl   [url] : full URL to get to TestRail index document
+
+    --password [key] : Your TestRail Password.
+
+    --user    [name] : Your TestRail User Name.
+
+=head3 BEHAVIOR
+
+    --case-ok      : Whether to consider each OK to correspond to a test in TestRail
+
+    --step-results [name] : 'System Name' of a 'step_results' type field to set for your tests.
+
+These options are mutually exclusive.  If neither is set, the
+overall result of the test will be used as the pass/fail for the test.
+
+=head2 PROVE PLUGIN:
+
+passing -PTestRail=apiurl,user,pass,project,run to prove will
+automatically upload your test results while the test is running if
+real-time results are desired.
+
+See L<App::Prove::Plugin::TestRail> for more information.
+
+=head2 REQUIREMENTS:
+
+Your TestRail install must have 3 custom statuses with the internal
+names 'skip', 'todo_pass', and 'todo_fail', to represent those
+states which TAP can have.
+
+=cut
+
 use strict;
 use strict;
 use warnings;
 use warnings;
 
 
 use Getopt::Long;
 use Getopt::Long;
 use Term::ANSIColor qw(colorstrip);
 use Term::ANSIColor qw(colorstrip);
 use Test::Rail::Parser;
 use Test::Rail::Parser;
+use IO::Interactive::Tiny ();
 
 
 print "testrail-report\n----------------------\n";
 print "testrail-report\n----------------------\n";
 
 
@@ -36,8 +103,6 @@ PARAMETERS:
   these in as needed, supposing you are not redirecting input
   these in as needed, supposing you are not redirecting input
   (such as piping into this command).
   (such as piping into this command).
 
 
-  [OPTIONS]
-
   [CONFIG OVERRIDES]
   [CONFIG OVERRIDES]
   In your \$HOME, put a file called .testrailrc with key=value
   In your \$HOME, put a file called .testrailrc with key=value
   syntax separated by newlines.  Valid Keys are: apiurl,user,password
   syntax separated by newlines.  Valid Keys are: apiurl,user,password
@@ -65,6 +130,8 @@ PROVE PLUGIN:
   automatically upload your test results while the test is running if
   automatically upload your test results while the test is running if
   real-time results are desired.
   real-time results are desired.
 
 
+  See App::Prove::Plugin::TestRail for more information.
+
 REQUIREMENTS:
 REQUIREMENTS:
   Your TestRail install must have 3 custom statuses with the internal
   Your TestRail install must have 3 custom statuses with the internal
   names 'skip', 'todo_pass', and 'todo_fail', to represent those
   names 'skip', 'todo_pass', and 'todo_fail', to represent those
@@ -136,13 +203,14 @@ if ($file) {
     close($fh);
     close($fh);
 } else {
 } else {
     #Just read STDIN, print help if no file was passed
     #Just read STDIN, print help if no file was passed
-    if (-t STDIN) { help(); }
+    if (IO::Interactive::Tiny::is_interactive()) { print "ERROR: no file passed, and no data piped in! See --help for usage." }
     if ( !$run || !$apiurl || !$password || !$user || !$project ) { print "ERROR: Interactive mode not allowed when piping input.  See --help for options.\n"; exit 0;};
     if ( !$run || !$apiurl || !$password || !$user || !$project ) { print "ERROR: Interactive mode not allowed when piping input.  See --help for options.\n"; exit 0;};
     while (<>) {
     while (<>) {
         $_ = colorstrip($_); #strip prove brain damage
         $_ = colorstrip($_); #strip prove brain damage
         s/^\s*//g; #Fix prove brain damage
         s/^\s*//g; #Fix prove brain damage
         $fcontents .= $_;
         $fcontents .= $_;
     }
     }
+    help() if !$fcontents; #Nothing passed to stdin!
 }
 }
 
 
 #Interrogate user if they didn't provide info
 #Interrogate user if they didn't provide info
@@ -195,3 +263,17 @@ print "Done.\n";
 
 
 #all done
 #all done
 0;
 0;
+
+__END__
+
+=head1 SEE ALSO
+
+L<TestRail::API>
+
+L<App::Prove::Plugin::TestRail>
+
+L<TAP::Parser>
+
+=head1 SPECIAL THANKS
+
+Thanks to cPanel Inc, for graciously funding the creation of this module.

+ 9 - 1
dist.ini

@@ -1,6 +1,6 @@
 name = TestRail-API
 name = TestRail-API
 main_module = lib/TestRail/API.pm
 main_module = lib/TestRail/API.pm
-version = 0.011
+version = 0.012
 author = George S. Baugh <teodesian@cpan.org>
 author = George S. Baugh <teodesian@cpan.org>
 license = Perl_5
 license = Perl_5
 copyright_holder = George S. Baugh
 copyright_holder = George S. Baugh
@@ -33,6 +33,7 @@ stopwords = createPlan
 stopwords = createProject
 stopwords = createProject
 stopwords = createRun
 stopwords = createRun
 stopwords = createTestSuite
 stopwords = createTestSuite
+stopwords = createTestResults
 stopwords = deleteCase
 stopwords = deleteCase
 stopwords = deleteMilestone
 stopwords = deleteMilestone
 stopwords = deletePlan
 stopwords = deletePlan
@@ -74,6 +75,13 @@ stopwords = api
 stopwords = ipsa
 stopwords = ipsa
 stopwords = loquiter
 stopwords = loquiter
 stopwords = testsuite
 stopwords = testsuite
+stopwords = testrail
+stopwords = EOFCallback
+stopwords = commentCallback
+stopwords = testCallback
+stopwords = unknownCallback
+stopwords = buildStepResults
+stopwords = testrailrc
 
 
 [PkgVersion]
 [PkgVersion]
 [AutoPrereqs]
 [AutoPrereqs]

BIN
dist/TestRail-API-0.012.tar.gz


+ 8 - 1
lib/App/Prove/Plugin/TestRail.pm

@@ -31,6 +31,13 @@ If ~/.testrailrc exists, it will be parsed for any of these values in a newline
 
 
 Be aware that if you do so, it will look for any unsatisfied arguments in the order of their appearance above.
 Be aware that if you do so, it will look for any unsatisfied arguments in the order of their appearance above.
 
 
+=head1 OVERRIDDEN METHODS
+
+=head2 load(parser)
+
+Shoves the arguments passed to the prove plugin into $ENV so that Test::Rail::Parser can get at them.
+Not the most elegant solution, but I see no other clear path to get those variables downrange to it's constructor.
+
 =cut
 =cut
 
 
 sub load {
 sub load {
@@ -61,7 +68,7 @@ sub load {
     $ENV{'TESTRAIL_RUN'}    = $run;
     $ENV{'TESTRAIL_RUN'}    = $run;
     $ENV{'TESTRAIL_CASEOK'} = $case_per_ok;
     $ENV{'TESTRAIL_CASEOK'} = $case_per_ok;
     $ENV{'TESTRAIL_STEPS'}  = $step_results;
     $ENV{'TESTRAIL_STEPS'}  = $step_results;
-
+    return $class;
 }
 }
 
 
 sub _parseConfig {
 sub _parseConfig {

+ 14 - 0
lib/Test/Rail/Harness.pm

@@ -11,6 +11,14 @@ use base qw/TAP::Harness/;
 
 
 Connective tissue for App::Prove::Plugin::TestRail.  Nothing to see here...
 Connective tissue for App::Prove::Plugin::TestRail.  Nothing to see here...
 
 
+Subclass of TAP::Harness.
+
+=head1 OVERRIDDEN METHODS
+
+=head2 new
+
+Tells the harness to use Test::Rail::Parser and passes off to the parent.
+
 =cut
 =cut
 
 
 # inject parser_class as Test::Rail::Parser.
 # inject parser_class as Test::Rail::Parser.
@@ -22,6 +30,12 @@ sub new {
     return $self;
     return $self;
 }
 }
 
 
+=head2 make_parser
+
+Picks the arguments passed to App::Prove::Plugin::TestRail out of $ENV and shuttles them to it's constructor.
+
+=cut
+
 sub make_parser {
 sub make_parser {
     my ($self, $job) = @_;
     my ($self, $job) = @_;
     my $args = $self->SUPER::_get_parser_args($job);
     my $args = $self->SUPER::_get_parser_args($job);

+ 37 - 6
lib/Test/Rail/Parser.pm

@@ -24,7 +24,7 @@ Has several options as to how you might want to upload said results.
 
 
 Subclass of L<TAP::Parser>, see that for usage past the constructor.
 Subclass of L<TAP::Parser>, see that for usage past the constructor.
 
 
-You should probably use L<App::Prove::Plugin::TestRail> or L<testrail-report> for day-to-day usage...
+You should probably use L<App::Prove::Plugin::TestRail> or the bundled program testrail-report for day-to-day usage...
 unless you need to subclass this.  In that case a couple of options have been exposed for your convenience.
 unless you need to subclass this.  In that case a couple of options have been exposed for your convenience.
 
 
 =cut
 =cut
@@ -41,7 +41,7 @@ Get the TAP Parser ready to talk to TestRail, and register a bunch of callbacks
 
 
 =over 4
 =over 4
 
 
-=item B<apiurl> - STRING: Full URI to your testRail's indexDocument.
+=item B<apiurl> - STRING: Full URI to your TestRail installation.
 
 
 =item B<user> - STRING: Name of your TestRail user.
 =item B<user> - STRING: Name of your TestRail user.
 
 
@@ -63,9 +63,9 @@ Get the TAP Parser ready to talk to TestRail, and register a bunch of callbacks
 
 
 =item B<case_per_ok> - BOOLEAN (optional): Consider test files to correspond to section names, and test steps (OKs) to correspond to tests in TestRail.  Mutually exclusive with step_results.
 =item B<case_per_ok> - BOOLEAN (optional): Consider test files to correspond to section names, and test steps (OKs) to correspond to tests in TestRail.  Mutually exclusive with step_results.
 
 
-=item B<result_options> - HASHREF (optional): Extra options to set with your result.  See L<TestRail::API>'s createTestResult function for more information.
+=item B<result_options> - HASHREF (optional): Extra options to set with your result.  See L<TestRail::API>'s createTestResults function for more information.
 
 
-=item B<custom_options> - HASHREF (optional): Custom options to set with your result.  See L<TestRail::API>'s createTestResult function for more information.  step_results will be set here, if the option is passed.
+=item B<custom_options> - HASHREF (optional): Custom options to set with your result.  See L<TestRail::API>'s createTestResults function for more information.  step_results will be set here, if the option is passed.
 
 
 =back
 =back
 
 
@@ -171,6 +171,14 @@ sub new {
     return $self;
     return $self;
 }
 }
 
 
+=head1 PARSER CALLBACKS
+
+=head2 unknownCallback
+
+Called whenever we encounter an unknown line in TAP.  Only useful for prove output, as we might pick a filename out of there.
+Stores said filename for future use if encountered.
+
+=cut
 
 
 # Look for file boundaries, etc.
 # Look for file boundaries, etc.
 sub unknownCallback {
 sub unknownCallback {
@@ -180,7 +188,7 @@ sub unknownCallback {
 
 
     #try to pick out the filename if we are running this on TAP in files
     #try to pick out the filename if we are running this on TAP in files
 
 
-    #old cpprove
+    #old prove
     if ($line =~ /^Running\s(.*)/) {
     if ($line =~ /^Running\s(.*)/) {
         #TODO figure out which testsuite this implies
         #TODO figure out which testsuite this implies
         $self->{'file'} = $1;
         $self->{'file'} = $1;
@@ -194,6 +202,13 @@ sub unknownCallback {
     print "$line\n" if ($line =~ /^error/i);
     print "$line\n" if ($line =~ /^error/i);
 }
 }
 
 
+=head2 commentCallback
+
+Grabs comments preceding a test so that we can include that as the test's notes.
+Especially useful when merge=1 is passed to the constructor.
+
+=cut
+
 # Register the current suite or test desc for use by test callback, if the line begins with the special magic words
 # Register the current suite or test desc for use by test callback, if the line begins with the special magic words
 sub commentCallback {
 sub commentCallback {
     my (@args) = @_;
     my (@args) = @_;
@@ -207,9 +222,17 @@ sub commentCallback {
     }
     }
 
 
     #keep all comments before a test that aren't these special directives to save in NOTES field of reportTCResult
     #keep all comments before a test that aren't these special directives to save in NOTES field of reportTCResult
-    $self->{'tr_opts'}->{'test_notes'} .= $line;
+    $self->{'tr_opts'}->{'test_notes'} .= "$line\n";
 }
 }
 
 
+=head2 testCallback
+
+If we are using step_results, append it to the step results array for use at EOF.
+If we are using case_per_ok, update TestRail per case.
+Otherwise, do nothing.
+
+=cut
+
 sub testCallback {
 sub testCallback {
     my (@args) = @_;
     my (@args) = @_;
     my $test = $args[0];
     my $test = $args[0];
@@ -276,6 +299,14 @@ sub testCallback {
     $self->{'tr_opts'}->{'test_desc'} = undef;
     $self->{'tr_opts'}->{'test_desc'} = undef;
 }
 }
 
 
+=head2 EOFCallback
+
+If we are running in step_results mode, send over all the step results to TestRail.
+If we are running in case_per_ok mode, do nothing.
+Otherwise, upload the overall results of the test to TestRail.
+
+=cut
+
 sub EOFCallback {
 sub EOFCallback {
     our $self;
     our $self;
 
 

+ 3 - 2
lib/TestRail/API.pm

@@ -1561,7 +1561,7 @@ Creates a result entry for a test.
 
 
 =item HASHREF C<OPTIONS> (optional) - Various "Baked-In" options that can be set for test results.  See TR docs for more information.
 =item HASHREF C<OPTIONS> (optional) - Various "Baked-In" options that can be set for test results.  See TR docs for more information.
 
 
-=item HASHREF C<CUSTOM OPTIONS> (optional) - Options to set for custom fields.  See L<TestRail::API::buildStepResults> for a simple way to post up custom steps.
+=item HASHREF C<CUSTOM OPTIONS> (optional) - Options to set for custom fields.  See buildStepResults for a simple way to post up custom steps.
 
 
 =back
 =back
 
 
@@ -1635,7 +1635,7 @@ Get the recorded results for desired test, limiting output to 'limit' entries.
 
 
 =item POSITIVE INTEGER C<LIMIT> (OPTIONAL) - provide no more than this number of results.
 =item POSITIVE INTEGER C<LIMIT> (OPTIONAL) - provide no more than this number of results.
 
 
-=item INTEGER C<OFFSET> (OPTIONAL) - Offset to begin viewing resultset at.
+=item INTEGER C<OFFSET> (OPTIONAL) - Offset to begin viewing result set at.
 
 
 =back
 =back
 
 
@@ -1660,6 +1660,7 @@ sub getTestResults {
 =head2 B<buildStepResults(content,expected,actual,status_id)>
 =head2 B<buildStepResults(content,expected,actual,status_id)>
 
 
 Convenience method to build the stepResult hashes seen in the custom options for getTestResults.
 Convenience method to build the stepResult hashes seen in the custom options for getTestResults.
+
 =over 4
 =over 4
 
 
 =item STRING C<CONTENT> (optional) - The step itself.
 =item STRING C<CONTENT> (optional) - The step itself.

+ 3 - 3
t/Test-Rail-Parser.t

@@ -61,7 +61,7 @@ if (!$res) {
 undef $tap;
 undef $tap;
 $res = exception {
 $res = exception {
     $tap = Test::Rail::Parser->new({
     $tap = Test::Rail::Parser->new({
-        'source'              => 'fake.test',
+        'source'              => 't/fake.test',
         'apiurl'              => $apiurl,
         'apiurl'              => $apiurl,
         'user'                => $login,
         'user'                => $login,
         'pass'                => $pw,
         'pass'                => $pw,
@@ -85,7 +85,7 @@ if (!$res) {
 undef $tap;
 undef $tap;
 $res = exception {
 $res = exception {
     $tap = Test::Rail::Parser->new({
     $tap = Test::Rail::Parser->new({
-        'source'              => 'faker.test',
+        'source'              => 't/faker.test',
         'apiurl'              => $apiurl,
         'apiurl'              => $apiurl,
         'user'                => $login,
         'user'                => $login,
         'pass'                => $pw,
         'pass'                => $pw,
@@ -109,7 +109,7 @@ if (!$res) {
 undef $tap;
 undef $tap;
 $res = exception {
 $res = exception {
     $tap = Test::Rail::Parser->new({
     $tap = Test::Rail::Parser->new({
-        'source'              => 'faker.test',
+        'source'              => 't/faker.test',
         'apiurl'              => $apiurl,
         'apiurl'              => $apiurl,
         'user'                => $login,
         'user'                => $login,
         'pass'                => $pw,
         'pass'                => $pw,