我們的網絡應用程序與幾個我們無法影響的網絡服務一起工作。在每個工作流程(使用Selenium進行測試)之後,會發生對Web服務的掛接調用。我想嘲笑那臺服務器。理想情況下,我需要一個HTTP服務器對象,我可以隨意啓動並殺死它,還有一個URL調度程序,它可以在調用時在我的測試中調用某些子例程。如何在Perl中模擬Web服務器?
到目前爲止,我發現HTTP::Server::Simple
和HTTP::Server::Brick
,我發現後者更吸引人。你有其他的內幕消息嗎?
我們的網絡應用程序與幾個我們無法影響的網絡服務一起工作。在每個工作流程(使用Selenium進行測試)之後,會發生對Web服務的掛接調用。我想嘲笑那臺服務器。理想情況下,我需要一個HTTP服務器對象,我可以隨意啓動並殺死它,還有一個URL調度程序,它可以在調用時在我的測試中調用某些子例程。如何在Perl中模擬Web服務器?
到目前爲止,我發現HTTP::Server::Simple
和HTTP::Server::Brick
,我發現後者更吸引人。你有其他的內幕消息嗎?
我發現HTTP::Request::AsCGI
對測試實現CGI接口的Web應用程序很有用。在來電方,它的行爲如同HTTP::Request
。
您可能想嘗試實現與外部API的接口,作爲CGI.pm
兼容模塊。
Net::HTTPServer非常靈活,比較成熟。
它可以基於URL路徑調用subs。
舉一個很好的例子來看看WWW::Mechanize的測試套件,它使用HTTP::Server::Simple::CGI。
我使用了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 ([email protected])
{
$c->send_error('500', [email protected]);
}
}
else
{
$c->send_error('404', 'No Template Found');
}
}
}
};
if ([email protected])
{
# Remove pid file
unlink "/tmp/httpd.pid";
# die
die [email protected];
}
# 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
測試代碼然後可以這樣寫:
#!/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;
催化劑也做到這一點。 – 2009-07-15 20:39:58