我们的网络应用程序与多个我们无法影响的网络服务协同工作。在每个工作流程(使用Selenium测试)之后,发生对Web服务的挂钩调用。我想嘲笑那个服务器。理想情况下,我想要一个HTTP服务器对象,我可以随意启动和终止,以及一个URL调度程序,它会在调用时调用我测试中的某些子程序。
到目前为止,我找到了HTTP::Server::Simple
和HTTP::Server::Brick
,我发现后者更具吸引力。你还有其他内幕消息吗?
答案 0 :(得分:5)
我使用了HTTP :: Daemon和Template :: Toolkit的组合来做到这一点。
package Test::WebService;
use HTTP::Daemon;
use HTTP::Response;
use IO::File;
use Template;
our $PID = $$;
END { __PACKAGE__->StopWeb(); }
sub StartWeb : method {
my $self = shift;
my $port = shift;
my %actions = $_[0] && ref($_[0]) eq 'HASH' ? %{ $_[0] } : @_ %2 ? () : @_;
# Ignore CHLD
local $SIG{CHLD} = 'IGNORE';
# Fork
my $pid = fork();
if ( $pid == 0 )
{
# Create pid file
_createPid( "/tmp/httpd.pid" );
# Create server
eval
{
# Create socket
my $d = HTTP::Daemon->new
(
Listen => 1,
LocalPort => $port,
Reuse => 1,
) || die "Failed to bind socket";
# Listen for connections
while ( my $c = $d->accept )
{
# Process requests
while ( my $r = $c->get_request() )
{
if ( defined( my $tmpl = $actions{ $r->uri()->path() } ) )
{
eval
{
# Create template object
my $tt = Template->new( {ABSOLUTE => 1 } );
# Create response
my $rs = HTTP::Response->new('200');
# Process template
$tt->process
(
$tmpl,
$r->uri()->query_form_hash(),
sub { $rs->content( shift ) }
);
# Send response
$c->send_response( $rs );
};
if ($@)
{
$c->send_error('500', $@ );
}
}
else
{
$c->send_error('404', 'No Template Found');
}
}
}
};
if ($@)
{
# Remove pid file
unlink "/tmp/httpd.pid";
# die
die $@;
}
# Exit nicely
exit(0);
}
# Wait up to 5 seconds for server to start;
die "Failed to start http server" unless _waitpid( 5, "/tmp/httpd.pid" );
}
sub StopWeb {
# Only cleanup parent process.
if ( $PID && $PID == $$ )
{
if ( my $fh = IO::File->new( "/tmp/httpd.pid", 'r') )
{
# Get pid.
my $pid;
$fh->read( $pid, 16384 );
$pid =~ s/\D//g;
# Kill server
kill 4, $pid if $pid;
}
}
}
sub _createPid {
my $fh = IO::File->new( shift, 'w') || die "Couldn't create pid";
$fh->print("$$");
$fh->close();
return;
}
sub _waitpid {
my $secs = shift || 5;
my $file = shift || die "Missing pid file";
for( my $i=0; $i
The Test code could then be written like:
#!/usr/bin/perl
use Test::More tests => 1;
use Test::WebService;
use MyApp;
Test::WebService->StartWeb( '8088', '/webservice/method' => 'my.tmpl' );
ok ( MyApp->methodThatCallsWebService(), 'yay!' );
1;
答案 1 :(得分:2)
有关好的示例,请查看WWW::Mechanize的测试套件,该套件使用HTTP::Server::Simple::CGI。
答案 2 :(得分:1)
我发现HTTP::Request::AsCGI
对于测试实现CGI接口的Web应用程序非常有用。在呼叫者方面,它的行为类似于HTTP::Request
。
您可能希望尝试将外部API的接口实现为CGI.pm
兼容模块。
答案 3 :(得分:0)
Net::HTTPServer非常灵活且相对成熟。
它可以根据URL路径调用subs。
答案 4 :(得分:0)
另一种完全适合测试的可能性:Test :: Fake :: HTTPD。