testrail-replay 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #!/usr/bin/perl
  2. # ABSTRACT: List runs in a TestRail project matching the provided filters
  3. # PODNAME: TestRail::Bin::Replay
  4. =head1 SYNOPSIS
  5. testrail-replay [OPTIONS] NAME
  6. require `which testrail-runs`;
  7. TestRail::Bin::Replay::run('args' => \@args);
  8. =head1 DESCRIPTION
  9. testrail-replay - Re-play the results of a test run or plan as though executed by prove.
  10. Optionally wait for results to come in.
  11. Can be used as the modulino TestRail::Bin::Replay.
  12. Has a single 'run' function which accepts a hash with the 'args' parameter being the array of arguments.
  13. =head1 PARAMETERS:
  14. =head2 MANDATORY PARAMETERS
  15. =over 4
  16. --apiurl : full URL to get to TestRail index document
  17. --password : Your TestRail Password, or a valid API key (TestRail 4.2 and above).
  18. --user : Your TestRail User Name.
  19. -j --project : desired project name.
  20. =back
  21. All mandatory options not passed with the above switches, or in your ~/.testrailrc will be prompted for.
  22. =head2 OPTIONAL PARAMETERS
  23. =over 4
  24. -p --plan : Instead of a run to look for, look for a plan with the provided NAME.
  25. -e --encoding : Character encoding of arguments. Defaults to UTF-8. See L<Encode::Supported> for supported encodings.
  26. -v --verbose : Print full test output rather than summaries with links to the testrail result.
  27. -w --watch : Watch tests until all report results other than untested or re-test.
  28. =back
  29. =head1 CONFIGURATION FILE
  30. In your \$HOME, (or the current directory, if your system has no concept of a home directory) put a file called .testrailrc with key=value syntax separated by newlines.
  31. Valid Keys are the same as documented by L<App::Prove::Plugin::TestRail>.
  32. All options specified thereby are overridden by passing the command-line switches above.
  33. =head1 MISCELLANEOUS OPTIONS:
  34. =over 4
  35. --help : show this output
  36. =back
  37. =cut
  38. package TestRail::Bin::Replay;
  39. use strict;
  40. use warnings;
  41. use TestRail::API;
  42. use TestRail::Utils;
  43. use TestRail::Utils::Find;
  44. use Getopt::Long qw{GetOptionsFromArray};
  45. use File::HomeDir qw{my_home};
  46. if (!caller()) {
  47. my ($out,$code) = run('args' => \@ARGV);
  48. print $out;
  49. exit $code;
  50. }
  51. sub run {
  52. my %params = @_;
  53. my $opts = {};
  54. # Parse config file
  55. my $homedir = my_home() || '.';
  56. if (-e $homedir . '/.testrailrc') {
  57. $opts = TestRail::Utils::parseConfig($homedir);
  58. }
  59. GetOptionsFromArray($params{'args'},
  60. 'apiurl=s' => \$opts->{'apiurl'},
  61. 'password=s' => \$opts->{'password'},
  62. 'user=s' => \$opts->{'user'},
  63. 'j|project=s' => \$opts->{'project'},
  64. 'e|encoding=s' => \$opts->{'encoding'},
  65. 'p|plan' => \$opts->{'plan'},
  66. 'v|verbose' => \$opts->{'verbose'},
  67. 'w|watch' => \$opts->{'watch'},
  68. 'h|help' => \$opts->{'help'},
  69. );
  70. if ($opts->{help}) { return ('',TestRail::Utils::help()); }
  71. $opts->{'browser'} = $params{'browser'};
  72. TestRail::Utils::interrogateUser($opts,qw{apiurl user password project});
  73. my $tr = TestRail::Utils::getHandle($opts);
  74. my $project = $tr->getProjectByName($opts->{'project'});
  75. return ("No such project '$opts->{project}'",2) unless $project;
  76. my $subject = $ARGV[0];
  77. my ($runs,$plan);
  78. if ($opts->{'plan'}) {
  79. $plan = $tr->getPlanByName($project->{'id'},$subject);
  80. $runs = $tr->getChildRuns($plan) if $plan;
  81. } else {
  82. my $run = $tr->getRunByName($project->{'id'},$subject);
  83. push( @$runs, $run) if $run;
  84. }
  85. return ("No runs found matching your criterion.\n",1) unless ref $runs eq 'ARRAY' && @$runs;
  86. my @tests;
  87. foreach my $run (@$runs) {
  88. my $tests = $tr->getTests($run->{id});
  89. @$tests = map { $_->{config} = $run->{config}; $_ } @$tests;
  90. push( @tests, @{$tests}) if ref $tests eq 'ARRAY' && @$tests;
  91. }
  92. #TODO get status ids for untested/retest, check em
  93. my @retry_status_ids = $tr->statusNamesToIds(qw{untested retest});
  94. my @bad_status_ids = $tr->statusNamesToIds(qw{failed todo_pass});
  95. my $rc = 0;
  96. while (my $test = shift @tests) {
  97. my $results = $tr->getTestResults($test->{id},1);
  98. if ( !( ref $results eq 'ARRAY') || !@$results) {
  99. push(@tests,$test) if $opts->{watch};
  100. next;
  101. }
  102. my $result = $results->[0];
  103. next unless ref $result eq 'HASH';
  104. if (!grep { $result->{status_id} eq $_ } @retry_status_ids) {
  105. print $result->{comment}."\n" if $opts->{verbose};
  106. my $line = $test->{title};
  107. $line .= " ($test->{config})" if $test->{config};
  108. $line .= " ...";
  109. if (grep { $result->{status_id} eq $_ } @bad_status_ids) {
  110. $rc = 3;
  111. $line .= ' not';
  112. }
  113. print "# $opts->{apiurl}/index.php?/tests/view/$test->{id}\n";
  114. print "$line ok\n";
  115. next;
  116. }
  117. push(@tests,$test) if $opts->{watch};
  118. # If we have to wait, back off a little to not slam the server
  119. sleep 1;
  120. }
  121. return ("Done",$rc);
  122. }
  123. 1;
  124. __END__
  125. L<TestRail::API>
  126. L<File::HomeDir> for the finding of .testrailrc
  127. =head1 SPECIAL THANKS
  128. Thanks to cPanel Inc, for graciously funding the creation of this distribution.