Search code examples
perltestingwww-mechanizedancerpsgi

How can I test a Dancer application with Test::WWW::Mechanize::PSGI?


I'm not sure on the right way to set up the script app for www mechanize. I did try at least one alternate that works, however I'm trying to pass in configuration with the test so I can make logging quieter with the test suite.

#!/usr/bin/perl
use strict;
use warnings;
use Dancer qw(:syntax);
use MyApp;
use Test::More;
use Test::WWW::Mechanize::PSGI;
set apphandler => 'PSGI';
set log => 'warning';
set logger => 'note';

my $mech = Test::WWW::Mechanize::PSGI->new(
    app => dance, # app => do('bin/app.pl'), #
);

$mech->get_ok('/login') or diag $mech->content;
done_testing;

running do on the script seems to allow the test to run, but logging variables aren't set right and at the same time seems like there'd be a better way to do that.

update

I think I might be getting closer to a solution...

#!/usr/bin/perl
use strict;
use warnings;
use FindBin;
use Cwd qw( realpath );
use Dancer qw(:syntax);
use MyApp;
use Test::More;
use Test::WWW::Mechanize::PSGI;
set apphandler => 'PSGI';

my $appdir = realpath( "$FindBin::Bin/.." );
my $mech = Test::WWW::Mechanize::PSGI->new(
    app => sub {
        my $env = shift;
        setting(
            appname => 'MyApp',
            appdir => $appdir,
        );
        load_app 'MyApp';
        config->{environment} = 'test'; # setting test env specific in test.yml detected ok
        Dancer::Config->load;
        my $request = Dancer::Request->new( env => $env );
        Dancer->dance( $request );
    }
);

$mech->get_ok('/login') or diag $mech->content;


done_testing;

I took this from the Dancer::Deployment documentation for Plack PSGI. However, I'm getting a 500 error from the test.

t/001-login.t .. Subroutine main::pass redefined at t/001-login.t line 8
Prototype mismatch: sub main::pass: none vs (;$) at t/001-login.t line 8
Use of uninitialized value $_[0] in join or string at    /home/ccushing/perl5/perlbrew/perls/perl-5.14.1/lib/5.14.1/i686-linux/File/Spec/Unix.pm line 86.

# [2462] debug @0.004442> [hit #1]Adding mysql_enable_utf8 to DBI connection params to   enable UTF-8 support in /home/ccushing/perl5/perlbrew/perls/perl- 5.14.1/lib/site_perl/5.14.1/Dancer/Plugin/Database.pm l. 148
# [2462] debug @0.117566> [hit #1]Adding mysql_enable_utf8 to DBI connection params to enable UTF-8 support in /home/ccushing/perl5/perlbrew/perls/perl-5.14.1/lib/site_perl/5.14.1/Dancer/Plugin/Database.pm l. 148
# [2462] error @0.148703> [hit #1]request to /login crashed: '/login/default.tt' doesn't exist or not a regular file at /home/ccushing/perl5/perlbrew/perls/perl-5.14.1/lib/site_perl/5.14.1/Dancer.pm line 161 in /home/ccushing/perl5/perlbrew/perls/perl-5.14.1/lib/site_perl/5.14.1/Dancer/Handler.pm l. 84
# <h2>runtime error</h2><pre class="error">&#39;/login/default.tt&#39; doesn&#39;t exist or not a regular file at /home/ccushing/perl5/perlbrew/perls/perl-5.14.1/lib/site_perl/5.14.1/Dancer.pm line 161

The DBI errors aren't relevant here, but their part of the error output I get. I can't figure out why it can't find /login/default.tt. I'm guessing that it's problem is that it has no idea where my views folder is as the template in question is at views/login/default.tt. This view works fine in the browser even when running on plackup. I'm stumped.


Solution

  • This works under the circumstance that I symlink t/views to views I currently believe this is probably the result of a bug, so I filed one here, and created this test case repository.

    #!/usr/bin/perl
    use strict;
    use warnings;
    BEGIN {
        use Test::More;
        use namespace::clean qw( pass );
    }
    use FindBin;
    use Cwd qw( realpath );
    use Dancer qw( :syntax );
    #use MyApp;
    use Test::WWW::Mechanize::PSGI;
    set apphandler => 'PSGI';
    
    my $appdir = realpath( "$FindBin::Bin/.." );
    my $mech = Test::WWW::Mechanize::PSGI->new(
        app => sub {
            my $env = shift;
            setting(
                appname => 'MyApp',
                appdir => $appdir,
            );
            load_app 'MyApp';
            config->{environment} = 'test';
            Dancer::Config->load;
            my $request = Dancer::Request->new( env => $env );
            Dancer->dance( $request );
        }
    );
    
    $mech->get_ok('/') or diag $mech->content;
    
    done_testing;
    

    I set the logger and log in environments/test.yml.

    I still get these errors, and I'd like to see them fixed but not sure what causes them.

      Use of uninitialized value $_[0] in join or string at  /home/ccushing/perl5/perlbrew/perls/perl-5.14.1/lib/5.14.1/i686-linux/File/Spec/Unix.pm line 86.
    Use of uninitialized value $path in -e at /home/ccushing/perl5/perlbrew/perls/perl-5.14.1/lib/site_perl/5.14.1/Dancer/FileUtils.pm line 46.
    Use of uninitialized value in index at /home/ccushing/perl5/perlbrew/perls/perl-5.14.1/lib/site_perl/5.14.1/Dancer/Renderer.pm line 160.
    

    Hopefully someone can provide me with a better answer than I've been able to hammer through.