Test-Rail-Parser.t 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. #!/usr/bin/env perl
  2. use strict;
  3. use warnings;
  4. use FindBin;
  5. use lib "$FindBin::Bin/lib";
  6. use Scalar::Util qw{reftype};
  7. use TestRail::API;
  8. use Test::LWP::UserAgent::TestRailMock;
  9. use Test::Rail::Parser;
  10. use Test::More 'tests' => 99;
  11. use Test::Fatal qw{exception};
  12. #Same song and dance as in TestRail-API.t
  13. my $apiurl = $ENV{'TESTRAIL_API_URL'};
  14. my $login = $ENV{'TESTRAIL_USER'};
  15. my $pw = $ENV{'TESTRAIL_PASSWORD'};
  16. my $is_mock = (!$apiurl && !$login && !$pw);
  17. ($apiurl,$login,$pw) = ('http://testrail.local','teodesian@cpan.org','fake') if $is_mock;
  18. my ($debug,$browser);
  19. $debug = 1;
  20. if ($is_mock) {
  21. $browser = $Test::LWP::UserAgent::TestRailMock::mockObject;
  22. }
  23. #test exceptions...
  24. #TODO
  25. #case_per_ok mode
  26. my $fcontents = "
  27. fake.test ..
  28. 1..2
  29. ok 1 - STORAGE TANKS SEARED
  30. #goo
  31. not ok 2 - NOT SO SEARED AFTER ARR
  32. ";
  33. my $tap;
  34. my $opts = {
  35. 'tap' => $fcontents,
  36. 'apiurl' => $apiurl,
  37. 'user' => $login,
  38. 'pass' => $pw,
  39. 'debug' => $debug,
  40. 'browser' => $browser,
  41. 'run' => 'TestingSuite',
  42. 'project' => 'TestProject',
  43. 'merge' => 1,
  44. 'case_per_ok' => 1
  45. };
  46. my $res = exception { $tap = Test::Rail::Parser->new($opts) };
  47. is($res,undef,"TR Parser doesn't explode on instantiation");
  48. isa_ok($tap,"Test::Rail::Parser");
  49. if (!$res) {
  50. $tap->run();
  51. is($tap->{'errors'},0,"No errors encountered uploading case results");
  52. }
  53. undef $tap;
  54. delete $opts->{'tap'};
  55. $opts->{'source'} = 't/fake.test';
  56. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  57. is($res,undef,"TR Parser doesn't explode on instantiation");
  58. isa_ok($tap,"Test::Rail::Parser");
  59. if (!$res) {
  60. $tap->run();
  61. is($tap->{'errors'},0,"No errors encountered uploading case results");
  62. }
  63. $fcontents = "ok 1 - STORAGE TANKS SEARED
  64. # whee
  65. not ok 2 - NOT SO SEARED AFTER ARR
  66. # Failed test 'NOT SO SEARED AFTER ARR'
  67. # at t/fake.test line 10.
  68. # Looks like you failed 1 test of 2.
  69. ";
  70. like($tap->{'raw_output'},qr/SEARED\n# whee.*\n.*AFTER ARR\n\n.*Failed/msxi,"Full raw content uploaded in non step results mode");
  71. #Check that time run is being uploaded
  72. my $timeResults = $tap->{'tr_opts'}->{'testrail'}->getTestResults(1);
  73. if ( ( reftype($timeResults) || 'undef') eq 'ARRAY') {
  74. is( $timeResults->[0]->{'elapsed'}, '2s', "Plugin correctly sets elapsed time");
  75. } else {
  76. fail("Could not get test results to check elapsed time!");
  77. }
  78. #Check the time formatting routine.
  79. is(Test::Rail::Parser::_compute_elapsed(0,0),undef,"Elapsed computation correct at second boundary");
  80. is(Test::Rail::Parser::_compute_elapsed(0,61),'1m 1s',"Elapsed computation correct at minute boundary");
  81. is(Test::Rail::Parser::_compute_elapsed(0,3661),'1h 1m 1s',"Elapsed computation correct at hour boundary");
  82. is(Test::Rail::Parser::_compute_elapsed(0,86461),'24h 1m 1s',"Elapsed computation correct at day boundary");
  83. #Time for non case_per_ok mode
  84. undef $tap;
  85. $opts->{'source'} = 't/faker.test';
  86. $opts->{'run'} = 'OtherOtherSuite';
  87. delete $opts->{'case_per_ok'};
  88. $opts->{'step_results'} = 'step_results';
  89. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  90. is($res,undef,"TR Parser doesn't explode on instantiation");
  91. isa_ok($tap,"Test::Rail::Parser");
  92. if (!$res) {
  93. $tap->run();
  94. is($tap->{'errors'},0,"No errors encountered uploading case results");
  95. is($tap->{'global_status'},5, "Test global result is FAIL when one subtest fails even if there are TODO passes");
  96. subtest 'Timestamp/elapsed printed in step results' => sub {
  97. foreach my $result (@{$tap->{'tr_opts'}->{'result_custom_options'}->{'step_results'}}) {
  98. like($result->{'content'}, qr/^\[.*\(.*\)\]/i, "Timestamp printed in step results");
  99. }
  100. };
  101. }
  102. #Default mode
  103. undef $tap;
  104. delete $opts->{'step_results'};
  105. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  106. is($res,undef,"TR Parser doesn't explode on instantiation");
  107. isa_ok($tap,"Test::Rail::Parser");
  108. if (!$res) {
  109. $tap->run();
  110. is($tap->{'errors'},0,"No errors encountered uploading case results");
  111. my @matches = $tap->{'raw_output'} =~ m/^(\[.*\(.*\)\])/msgi;
  112. ok(scalar(@matches),"Timestamps present in raw TAP");
  113. }
  114. #Default mode
  115. undef $tap;
  116. $fcontents = "
  117. fake.test ..
  118. 1..2
  119. ok 1 - STORAGE TANKS SEARED
  120. #Subtest NOT SO SEARED AFTER ARR
  121. ok 1 - STROGGIFY POPULATION CENTERS
  122. not ok 2 - STROGGIFY POPULATION CENTERS
  123. #goo
  124. not ok 2 - NOT SO SEARED AFTER ARR
  125. ";
  126. $opts->{'tap'} = $fcontents;
  127. delete $opts->{'source'};
  128. delete $opts->{'step_results'};
  129. $opts->{'run'} = 'TestingSuite';
  130. $opts->{'case_per_ok'} = 1;
  131. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  132. is($res,undef,"TR Parser doesn't explode on instantiation");
  133. isa_ok($tap,"Test::Rail::Parser");
  134. if (!$res) {
  135. $tap->run();
  136. is($tap->{'errors'},0,"No errors encountered uploading case results");
  137. }
  138. #skip/todo in case_per_ok
  139. undef $tap;
  140. delete $opts->{'tap'};
  141. $opts->{'source'} = 't/skip.test';
  142. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  143. is($res,undef,"TR Parser doesn't explode on instantiation");
  144. isa_ok($tap,"Test::Rail::Parser");
  145. if (!$res) {
  146. $tap->run();
  147. is($tap->{'errors'},0,"No errors encountered uploading case results");
  148. }
  149. #Default mode skip (skip_all)
  150. undef $tap;
  151. $opts->{'source'} = 't/skipall.test';
  152. delete $opts->{'case_per_ok'};
  153. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  154. is($res,undef,"TR Parser doesn't explode on instantiation");
  155. isa_ok($tap,"Test::Rail::Parser");
  156. if (!$res) {
  157. $tap->run();
  158. is($tap->{'errors'},0,"No errors encountered uploading case results");
  159. is($tap->{'global_status'},6, "Test global result is SKIP on skip all");
  160. }
  161. #Ok, let's test the plan, config, and spawn bits.
  162. undef $tap;
  163. $opts->{'run'} = 'hoo hoo I do not exist';
  164. $opts->{'plan'} = 'mah dubz plan';
  165. $opts->{'configs'} = ['testPlatform1'];
  166. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  167. isnt($res,undef,"TR Parser explodes on instantiation when asking for run not in plan");
  168. undef $tap;
  169. $opts->{'run'} = 'TestingSuite';
  170. $opts->{'configs'} = ['testConfig'];
  171. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  172. is($res,undef,"TR Parser doesn't explode on instantiation looking for existing run in plan");
  173. isa_ok($tap,"Test::Rail::Parser");
  174. if (!$res) {
  175. $tap->run();
  176. is($tap->{'errors'},0,"No errors encountered uploading case results");
  177. }
  178. #Now, test spawning.
  179. undef $tap;
  180. $opts->{'run'} = 'TestingSuite2';
  181. $opts->{'configs'} = ['testPlatform1'];
  182. $opts->{'testsuite_id'} = 9;
  183. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  184. is($res,undef,"TR Parser doesn't explode on instantiation when spawning run in plan");
  185. isa_ok($tap,"Test::Rail::Parser");
  186. if (!$res) {
  187. $tap->run();
  188. is($tap->{'errors'},0,"No errors encountered uploading case results");
  189. }
  190. #Test spawning of builds not in plans.
  191. #Now, test spawning.
  192. undef $tap;
  193. delete $opts->{'testsuite_id'};
  194. delete $opts->{'plan'};
  195. delete $opts->{'configs'};
  196. $opts->{'testsuite'} = 'HAMBURGER-IZE HUMANITY';
  197. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  198. is($res,undef,"TR Parser doesn't explode on instantiation when spawning run in plan");
  199. isa_ok($tap,"Test::Rail::Parser");
  200. if (!$res) {
  201. $tap->run();
  202. is($tap->{'errors'},0,"No errors encountered uploading case results");
  203. }
  204. #Test spawning of plans and runs.
  205. undef $tap;
  206. $opts->{'run'} = 'BogoRun';
  207. $opts->{'plan'} = 'BogoPlan';
  208. $opts->{'testsuite_id'} = 9;
  209. delete $opts->{'testsuite'};
  210. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  211. is($res,undef,"TR Parser doesn't explode on instantiation when spawning run in plan");
  212. isa_ok($tap,"Test::Rail::Parser");
  213. if (!$res) {
  214. $tap->run();
  215. is($tap->{'errors'},0,"No errors encountered uploading case results");
  216. }
  217. #Verify that case_per_ok and step_results are mutually exclusive, and die.
  218. undef $tap;
  219. $opts->{'case_per_ok'} = 1;
  220. $opts->{'step_results'} = 'sr_step_results';
  221. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  222. isnt($res,undef,"TR Parser explodes on instantiation when mutually exclusive options are passed");
  223. #Check that per-section spawn works
  224. undef $tap;
  225. $opts->{'source'} = 't/fake.test';
  226. delete $opts->{'plan'};
  227. $opts->{'sections'} = ['fake.test'];
  228. delete $opts->{'step_results'};
  229. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  230. is($res,undef,"TR Parser doesn't explode on instantiation");
  231. isa_ok($tap,"Test::Rail::Parser");
  232. if (!$res) {
  233. $tap->run();
  234. is($tap->{'errors'},0,"No errors encountered uploading case results");
  235. }
  236. #Check that per-section spawn works
  237. undef $tap;
  238. $opts->{'plan'} = 'BogoPlan';
  239. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  240. is($res,undef,"TR Parser doesn't explode on instantiation");
  241. isa_ok($tap,"Test::Rail::Parser");
  242. if (!$res) {
  243. $tap->run();
  244. is($tap->{'errors'},0,"No errors encountered uploading case results");
  245. }
  246. undef $tap;
  247. $opts->{'sections'} = ['potzrebie'];
  248. delete $opts->{'plan'};
  249. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  250. isnt($res,undef,"TR Parser explodes on instantiation with invalid section");
  251. undef $tap;
  252. $opts->{'source'} = 't/notests.test';
  253. delete $opts->{'sections'};
  254. delete $opts->{'case_per_ok'};
  255. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  256. is($res,undef,"TR Parser doesn't explode on instantiation");
  257. isa_ok($tap,"Test::Rail::Parser");
  258. if (!$res) {
  259. $tap->run();
  260. is($tap->{'errors'},0,"No errors encountered uploading case results");
  261. is($tap->{'global_status'},4, "Test global result is RETEST on env fail");
  262. }
  263. undef $tap;
  264. $opts->{'source'} = 't/pass.test';
  265. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  266. is($res,undef,"TR Parser doesn't explode on instantiation");
  267. isa_ok($tap,"Test::Rail::Parser");
  268. if (!$res) {
  269. $tap->run();
  270. is($tap->{'errors'},0,"No errors encountered uploading case results");
  271. is($tap->{'global_status'},1, "Test global result is PASS on ok test");
  272. }
  273. undef $tap;
  274. $opts->{'source'} = 't/todo_pass.test';
  275. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  276. is($res,undef,"TR Parser doesn't explode on instantiation");
  277. isa_ok($tap,"Test::Rail::Parser");
  278. if (!$res) {
  279. $tap->run();
  280. is($tap->{'errors'},0,"No errors encountered uploading case results");
  281. is($tap->{'global_status'},8, "Test global result is TODO PASS on todo pass test");
  282. }
  283. undef $tap;
  284. #Check bad plan w/ todo pass logic
  285. $fcontents = "
  286. todo_pass.test ..
  287. 1..2
  288. ok 1 - STORAGE TANKS SEARED #TODO todo pass
  289. # goo
  290. ";
  291. undef $opts->{'source'};
  292. $opts->{'tap'} = $fcontents;
  293. $opts->{'step_results'} = 'step_results';
  294. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  295. is($res,undef,"TR Parser doesn't explode on instantiation");
  296. isa_ok($tap,"Test::Rail::Parser");
  297. if (!$res) {
  298. $tap->run();
  299. is($tap->{'errors'},0,"No errors encountered uploading case results");
  300. is($tap->{'global_status'},5, "Test global result is FAIL on todo pass test w/ bad plan");
  301. my $srs = $tap->{'tr_opts'}->{'result_custom_options'}->{'step_results'};
  302. is($srs->[-1]->{'content'},"Bad Plan.","Bad plan noted in step results");
  303. }
  304. undef $opts->{'step_results'};
  305. #Check instant pizza
  306. $fcontents = "
  307. todo_pass.test ..
  308. 1..2
  309. ";
  310. undef $opts->{'source'};
  311. $opts->{'tap'} = $fcontents;
  312. $opts->{'step_results'} = 'step_results';
  313. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  314. is($res,undef,"TR Parser doesn't explode on instantiation");
  315. isa_ok($tap,"Test::Rail::Parser");
  316. if (!$res) {
  317. $tap->run();
  318. is($tap->{'errors'},0,"No errors encountered uploading case results");
  319. is($tap->{'global_status'},4, "Test global result is FAIL on todo pass test w/ bad plan");
  320. my $srs = $tap->{'tr_opts'}->{'result_custom_options'}->{'step_results'};
  321. is($srs->[-1]->{'content'},"Bad Plan.","Bad plan noted in step results");
  322. }
  323. undef $opts->{'step_results'};
  324. undef $tap;
  325. #Check bad plan w/ todo pass logic
  326. $fcontents = "
  327. todo_pass.test ..
  328. 1..2
  329. ok 1 - STORAGE TANKS SEARED #TODO todo pass
  330. # goo
  331. % mark_status=todo_fail #Appears tanks weren't so sealed after all
  332. ";
  333. undef $opts->{'source'};
  334. $opts->{'tap'} = $fcontents;
  335. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  336. is($res,undef,"TR Parser doesn't explode on instantiation");
  337. isa_ok($tap,"Test::Rail::Parser");
  338. if (!$res) {
  339. $tap->run();
  340. is($tap->{'errors'},0,"No errors encountered uploading case results");
  341. is($tap->{'global_status'},7, "Test global result is FAIL on todo pass test w/ bad plan");
  342. }
  343. undef $opts->{'tap'};
  344. #Check autoclose functionality against Run with all tests in run status.
  345. undef $tap;
  346. $opts->{'source'} = 't/skip.test';
  347. $opts->{'run'} = 'FinalRun';
  348. $opts->{'autoclose'} = 1;
  349. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  350. is($res,undef,"TR Parser doesn't explode on instantiation");
  351. isa_ok($tap,"Test::Rail::Parser");
  352. if (!$res) {
  353. $tap->run();
  354. is($tap->{'errors'},0,"No errors encountered uploading case results");
  355. is($tap->{'run_closed'},1, "Run closed by parser when all tests done");
  356. }
  357. #Check autoclose functionality against Run with not all tests in run status.
  358. undef $tap;
  359. $opts->{'source'} = 't/todo_pass.test';
  360. $opts->{'run'} = 'BogoRun';
  361. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  362. is($res,undef,"TR Parser doesn't explode on instantiation");
  363. isa_ok($tap,"Test::Rail::Parser");
  364. if (!$res) {
  365. $tap->run();
  366. is($tap->{'errors'},0,"No errors encountered uploading case results");
  367. is($tap->{'run_closed'},undef, "Run not closed by parser when results are outstanding");
  368. }
  369. #Check that autoclose works against plan wiht all tests in run status
  370. undef $tap;
  371. $opts->{'source'} = 't/fake.test';
  372. $opts->{'run'} = 'FinalRun';
  373. $opts->{'plan'} = 'FinalPlan';
  374. $opts->{'configs'} = ['testConfig'];
  375. $opts->{'case_per_ok'} = 1;
  376. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  377. is($res,undef,"TR Parser doesn't explode on instantiation");
  378. isa_ok($tap,"Test::Rail::Parser");
  379. if (!$res) {
  380. $tap->run();
  381. is($tap->{'errors'},0,"No errors encountered uploading case results");
  382. is($tap->{'plan_closed'},1, "Plan closed by parser when all tests done");
  383. }
  384. #Check that autoclose works against plan with all tests not in run status
  385. undef $tap;
  386. $opts->{'run'} = 'BogoRun';
  387. $opts->{'plan'} = 'BogoPlan';
  388. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  389. is($res,undef,"TR Parser doesn't explode on instantiation");
  390. isa_ok($tap,"Test::Rail::Parser");
  391. if (!$res) {
  392. $tap->run();
  393. is($tap->{'errors'},0,"No errors encountered uploading case results");
  394. is($tap->{'plan_closed'},undef, "Plan not closed by parser when results are outstanding");
  395. }
  396. #Plan but no run 'splodes
  397. undef $tap;
  398. $opts->{'plan'} = 'CompletePlan';
  399. delete $opts->{'run'};
  400. delete $opts->{'configs'};
  401. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  402. like($res,qr/but no run passed/i,"TR Parser explodes on instantiation due to passing plan with no run");
  403. #Check that trying without spawn opts, using completed plan fails
  404. undef $tap;
  405. $opts->{'plan'} = 'ClosedPlan';
  406. $opts->{'run'} = 'BogoRun';
  407. delete $opts->{'testsuite_id'};
  408. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  409. like($res,qr/plan provided is completed/i,"TR Parser explodes on instantiation due to passing closed plan");
  410. #Check that the above two will just spawn a new plan in these cases
  411. $opts->{'testsuite_id'} = 9;
  412. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  413. is($res,undef,"TR Parser runs all the way through on completed run when spawning");
  414. #Check that trying without spawn opts, using completed run fails
  415. undef $tap;
  416. delete $opts->{'testsuite_id'};
  417. delete $opts->{'plan'};
  418. $opts->{'run'} = 'ClosedRun';
  419. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  420. like($res,qr/run provided is completed/i,"TR Parser explodes on instantiation due to passing closed run");
  421. #Check that the above two will just spawn a new run in these cases
  422. $opts->{'testsuite_id'} = 9;
  423. $res = exception { $tap = Test::Rail::Parser->new($opts) };
  424. is($res,undef,"TR Parser runs all the way through on completed run when spawning");