2012-01-24 37 views
1

我正在構建一個perl應用程序來存檔簡單的網頁(即沒有涉及查詢字符串的靜態頁面)。我想編寫測試來驗證將訪問遠程文件的模塊的功能。爲了使測試能夠自我依賴,我正在尋找一個簡單的,自包含的測試腳本可以在本地使用的Web服務器。有沒有一種簡單的方法來設置本地,自包含的Web服務器進行Perl測試?

下面是一個例子,概述了我想要做的事情。我已經把它刪減到最低限度具有以下目錄結構: 「./MirrorPage.pm 」的

./MirrorPage.pm 
./t/001_get_url.t 
./t/test-docroot/test-1.json 

內容:的「 ./t/001_get_url.t」

package MirrorPage; 

use Moose; 
use LWP::Simple; 
use namespace::autoclean; 

sub get_url { 

    my ($self, $url_to_get) = @_; 

    ### grab the contents of the url 
    my $url_data = get($url_to_get); 

    ### return the contents. 
    return $url_data; 

} 

__PACKAGE__->meta->make_immutable; 

1; 

內容:

#!/usr/bin/perl 

use Modern::Perl; 
use Test::More; 
use MirrorPage; 

    ### Start test www server on port 8123 here ### 

my $t = new_ok('MirrorPage', undef, 'Create MirrorPage'); 

is(
    $t->get_url("http://localhost:8123/test-1.json"), 
    '{ testkey: "testvalue" }', 
    "Verify the data." 
); 

    ### Kill test www server here ### 

done_testing(); 

的 「./t/test-docroot/test-1.json」 內容:

{ testkey: "testvalue" } 

目標是在「./t/001_get_url.t」中相應的註釋位置啓動並終止一個自包含的Web服務器。 Web服務器需要將「./t/test-docroot」目錄的內容作爲其文檔根目錄。

鑑於以上所有內容:什麼是最佳/最簡單的方式來設置一個自包含的Web服務器提供靜態文件在Perl中測試?

+0

快速跟進。我已經將「ruz」的答案標記爲已接受,因爲它完全符合我對這個特定情況所需的最少量的大驚小怪。 「Chris J」關於使用MockObject的答案提供了一個更加通用的解決方案。值得檢查的是需要超越Web服務器的更復雜的測試。 –

回答

2

LWP可以獲取文件,因此您可以將重寫爲$url_to_getfile://...

+0

聖牛!很簡單。好棒。 –

-1

雖然它是特定操作系統,但我相信Apache是​​你的答案。

+0

我認爲OP是想讓這種情況自動發生,作爲模塊單元測試的一部分。取決於Apache是​​一個非啓動器,更不用說配置它,啓動和停止它。 – zgpmax

+0

我實際上試圖避免使用Apache。我已經在我的機器上安裝了幾個用於Web開發安裝的虛擬主機。我不想爲了提供測試文件而必須設置和拆卸更多。另外,它不能移植到其他機器上,也沒有設置它們的apache實例。 –

+0

有效點;那麼我會考慮Mondobill的決議。 – Hikalea

3

我會嘲笑你附近.T文件頂部的HTTP調用(如果你只是想測試MirrorPage.pm):

my $mock = new Test::MockObject(); 
$mock->fake_module('LWP::Simple', get => sub { return '{ testkey: "testvalue" }' }); 
+0

我不得不做一些改變才能使這個工作。 - 首先:將'... sub {return ...'改爲'... sub($){return ...'以避免關於Prototype不匹配的警告。 - 其次,我不得不改變'使用LWP :: Simple;'使用LWP :: Simple();'然後'我的$ url_data = get($ url_to_get);''我的$ url_data = LWP ::簡單::得到($ url_to_get);'。否則,模擬對象將不會覆蓋測試中的LWP :: Simple的「get」。一旦這些到位,這很好地工作。 –

2

也許:

在頂部,叉並使用HTTP::Server::Simple::Static做一個簡單的靜態文件服務器,然後在底部終止子進程。

+0

我正在沿着這些相同的線路移動。我交叉發佈了一個答案,使用相同的想法,但與Net :: HTTPServer相反。 –

1

這是我想出的使用Net::HTTPServer。基於「It’s OK to Ask and Answer Your Own Questions」的想法,我在這裏發表評論/考慮。我所做的是:

首先,在「./t/TestServer.pm」創建一個新模塊。這個文件的內容是:

package TestServer; 

use Moose; 
use Net::HTTPServer; 
use namespace::autoclean; 

has 'server' => (
    is => "rw", 
    isa => "Net::HTTPServer", 
    default => sub { 
     Net::HTTPServer->new (
      port => 8123, 
      docroot => "t/test-docroot" 
     ) 
    }, 
); 


sub BUILD { 

    my $self = shift; 

    ### Spin up the server. 
    $self->server->Start(); 
    $self->server->Process(); 

} 

### Close up the Moose package. 
__PACKAGE__->meta->make_immutable; 

1; 

然後,更新測試「./t/001_get_url.t」文件通過叉使用它:

#!/usr/bin/perl 

use Modern::Perl; 
use Test::More; 
use MirrorPage; 

### Fork for the server 
my $pid = fork(); 

### Parent process. Holds the tests. 
if($pid) { 

    ### Make sure the server has a moment to startup 
    sleep(2); 

    my $t = new_ok('MirrorPage', undef, 'Create MirrorPage'); 

    is(
     $t->get_url("http://localhost:8123/test-1.json"), 
     '{ testkey: "testvalue" }', 
     "Verify the data." 
    ); 
} 

### Child process. Holds the server. 
elsif(defined($pid)) { 

    use lib "t/"; 
    use TestServer; 

    my $svr = TestServer->new(); 

    exit; # Should never get here. 

} 

### Error out if necessary. 
else { 
    die "Can not fork child process."; 
} 


### Kill the server fork. 
kill 1, $pid; 

done_testing(); 

這是爲我工作很好。

+0

我對回答自己的問題的建議是等到第二天發佈答案。 –

+0

我可以看到。我也見過那些立刻說過的人。我走中間路線,等到有其他幾個答案(很快就出來了)。我也想過直接將我提出的解決方案放在問題中並要求反饋。我之前做過,但也感覺很奇怪。下次我有這樣的一個,我會在第二天給我一個鏡頭。 –

2

我強烈推薦Mojolicious作爲爲客戶端生成測試服務器的好方法。由於Mojolicious只是將URL映射到子例程調用中,因此很容易對服務器的功能進行非常好的控制,因此您可以輕鬆測試諸如「服務器返回錯誤響應/錯誤內容/超時「。由於設置和拆除服務器非常簡單,使用fork()可以使測試和服務器設置在同一個測試文件中。

+0

謝謝,喬。使用直接LWP調用file://系統正在爲我當前的測試工作。下次我需要做一些事情時,我會深入研究這一點。喜歡你可以做一些事情,比如退貨時間不足和內容不好。我期待着玩它。 –

相關問題