å¤é¨APIãå«ããWebã¢ããªã®ãã¹ãããã¦ã¿ã
å¤é¨APIãç¨ããWebã¢ããªã®ã³ã³ããã¼ã©ãã¹ãã«ã¤ãã¦ã
ãã¨ãã°
æ°å¤ã®ï¼ä¹ãçµæã¨ãã¦è¿ãAPIãµã¼ã
ãããã¨ãã¦ã
ãã®APIãå©ç¨ããçµæãHTMLã¨ãã¦åºåããã¢ããªã±ã¼ã·ã§ã³
ãèãã¦ã¿ã¾ãã
ãããããã®ããã«å¤é¨APIãµã¼ããç¨ããã¨ãã¹ããé£ãããªãã¾ãã
ããããããã¢ã¯ã»ã¹ã³ã³ããã¼ã«ããã¦ããããããã¾ãããã
ã¡ã³ããã³ã¹ããã¦ããããããã¾ãããã
ãªãã©ã¤ã³ã ã¨ãããããã¹ãã§ããªãã§ãããï¼
ããã§å¤é¨APIãµã¼ããæ¯èãplackãµã¼ãããã¼ã«ã«ã§ç«ã¡ä¸ãã¦
ãããproveã§å©ç¨ã§ããã¨ããããã
ã¨ããããã§ãã®ãããªç°å¢ãä½ã£ã¦ã¿ã¾ãã
ãµã³ãã«Webã¢ã㪠*1
ã¾ã㯠/api ã« ã¢ã¯ã»ã¹ãã㨠å¤é¨APIãµã¼ãã«ã¢ã¯ã»ã¹ãã¦ãã®çµæãè¿ãã ãã®ã³ã³ããã¼ã©ãæ¸ãã¦ã¿ã¾ãã
$host ã¯ãã¹ãããã³ã³ããã¼ã«ã§ããããã«ç°å¢å¤æ°ãã¿ã¦ãã¾ãã
lib/ApiSample/Web/C/Root.pm
package ApiSample::Web::C::Root; use strict; use warnings; use URI; sub index { my ($class, $c) = @_; $c->render("index.tt"); } sub api { my ($class, $c) = @_; my $num = $c->req->param('num') || 0; my $host = $ENV{API_SERVER} || "111.111.111.111"; my $uri = URI->new;; $uri->scheme("http"); $uri->host($host); $uri->path_query("/?num=$num"); my $ua = LWP::UserAgent->new; my $res = $ua->get($uri->as_string); unless ( $res->is_success ) { die $res->message; } $c->render("api.tt", {content => $res->content}); } 1;
ãã³ãã¬ã¼ã
tmpl/api.tt
<<<[% $content %]>>>
ãã¹ãç¨plackã¢ããªã®ä½æ
numãï¼ä¹ãã¦è¿ãã ãã®Webã¢ããªã
ãã¹ãã®è¦ä»¶ãæºããã ãã®ä½ãã«ãã¦ããã°ããã§ãããã
t/script/api.psgi
use strict; use warnings; use Plack::Request; my $app = sub { my $env = shift; my $req = Plack::Request->new($env); my $num = $req->param('num') || 0; my $body = $num ** 2; return [ 200, [ "Content-Type" => "text/plain"], [ $body ] ]; };
ãã¹ãã¯ã©ã¹ã®ä½æ
ãããªã®ãæ¸ãã¦ããã
èªåã®ç°å¢ã ã¨Test::mysqldã®ãã¹ãããã±ã¼ã¸ã¨ä¸ç·ã«ãã¦ããã
t/lib/ApiSample/Test.pm
package ApiSample::Test; use Any::Moose; # ... __PACKAGE__->meta->make_immutable; no Any::Moose; use Proc::Guard; use Plack::Util; # ... sub start_plackup { my $self = shift; my %args = @_; my $app = $args{app}; my $port = $args{port} || Test::TCP::empty_port(); my $envd = $args{envd} || 'deployment'; my @proc = ( plackup => (map { ( "-I" => $_ ) } @INC), '-p' => $port, '-a' => $app, '-E' => $envd, ); Proc::Guard::proc_guard(@proc); } 1;
ãã¹ããã¡ã¤ã«
ã¾ãæåã«ãã¹ãAPIç¨ã®plackã¢ããªãèµ·åãã¦ãµã¼ãæ
å ±ãç°å¢å¤æ°ã«ä¿åãã¾ãã
ãã®å¾mechããã¨ãã¹ãç¨ã®plackãµã¼ãã«æ¥ç¶ããã¾ãã
t/mech.t
use strict; use warnings; use Plack::Test; use Plack::Util; use Test::More; use Test::Requires 'Test::WWW::Mechanize::PSGI'; use lib "./t/lib"; use ApiSample::Test; use Test::TCP qw/wait_port/; # Web API ç¨ã®plackã¢ããªèµ·å my $t = ApiSample::Test->new(); my $port = '55551'; my $app_api = $t->start_plackup( app => 't/script/api.psgi', port => $port, envd => 'production', ); # ç«ã¡ä¸ããã¾ã§å¾ ã¤... wait_port($port); # Web API ç¨ã®ç°å¢å¤æ° $ENV{API_SERVER} = "localhost:$port"; # test my $app = Plack::Util::load_psgi 'ApiSample.psgi'; my $mech = Test::WWW::Mechanize::PSGI->new(app => $app); { my $uri = "/api?num=5"; $mech->get_ok($uri); $mech->head_ok($uri, ['Content-Type' => 'text/html']); $mech->content_like( qr/<<<25>>>/, 'ï¼ã®ï¼ä¹ãè¿ã£ã¦ããã¯ã'); } done_testing;
ãã¨ã¯proveããã ãã§OKã
æ°è¡ã®psgiæ¸ãã ãã§APIãå«ãããã¹ãããæè»½ã«åºæ¥ãã®ã§ã¦ãã¦ãã§ããï¼
plackãã³ã¶ã¤ï¼
ã¡ãªã¿ã«Test::mysqldã®ããã«å¸¸æèµ·åãããããªã¹ã¯ãªãããæ¸ãã¦ãããã¨æãã¾ããã
æ°ã«ãªãã»ã©é
ããªãã®ã§èªåã¯ãã®ã¾ã¾ã¤ãã£ã¦ã¾ã
â»åè
http://www.slideshare.net/lestrrat/why-dont-you-do-your-test-fukuoka-perl-workshop-18
*1:ãµã³ãã«ã§ã¯Amon2ãå©ç¨ãã¦ãã¾ã