Amit Bondwal Amit Bondwal - 14 days ago 5
Perl Question

Not able to print a variable/hash in a test case with Test::WWW::Mechanize::Catalyst in perl catalyst app

I am writing test cases for a Perl Catalyst based web application with Test::WWW::Mechanize::Catalyst. I stuck somewhere and I want to troubleshoot by printing a variable/hash value. But the problem is that it just show the console log of Catalyst App. How can I print a variable value in console? like in catalyst $c->log->info($variable value).

Answer

When you run your tests with prove you need to add the -v flag to see all the test output.

$ prove -v t/

That way it will not eat up all the TAP output.

You can then use diag from Test::More to output comments into the TAP, or the warn builtin.

use Test::More;

pass 'first test';
diag 'this is a diagnostical message';

my $res = pass 'another test';
warn $res;

done_testing;

That produces this output (on Windows):

$ prove -v foo.pl
foo.pl .. # this is a diagnostical message

1 at foo.pl line 7.
ok 1 - first test
ok 2 - another test
1..2
ok
All tests successful.
Files=1, Tests=2,  0 wallclock secs ( 0.02 usr +  0.02 sys =  0.03 CPU)
Result: PASS

However, what I usually do is to use Data::Printer's p function, which also writes to STDERR like a warning. It's a bit more powerful than Data::Dumper and displays objects nicely. The debug output from p will also just end up somewhere in the TAP.

It can get confusing if there is a lot of logging from the application going on, so turning off the Catalyst log is an option. To do that, run your tests with the environment variable CATALYST_DEBUG set to 0.

$ CATALYST_DEBUG=0 prove -v t/

If instead you want your debug output from the test go into the Catalyst log, you need to grab a context. That's a bit more tricky, but possible.

use Test::More
use Test::WWW::Mechanize::Catalyst;
use Catalyst::Test 'MyApp';
use Data::Printer;

my $mech = Test::WWW::Mechanize::Catalyst->new(catalyst_app => 'MyApp');

$mech->get_ok("/");

my($res, $c) = ctx_request('/');
$c->log->warn(np $res); # this will go to the Catalyst log

That code uses both Test::WWW::Mechanize::Catalyst and Catalyst::Test. If you pass the same app name they won't get into each other's way and the app will only be started once.

I'm showing a regular mech test with get_ok and the ctx_request function from Catalyst::Test. It returns an HTTP::Response object and the context $c from that request. You can run ->log on the context and your debugging will go to the Catalyst log. I'm using np from Data::Printer, which returns the debugging info generated by Data::Printer instead of writing it to STDOUT so I can put it into the Catalyst log.

Comments