2012-11-26 141 views
6

我是PHPUnit測試框架的新手。如何在php命令行中模擬文件上傳

因爲我們知道,PHP的move_uploaded_file()功能將無法正常工作,直到該文件是通過HTTP POST方法上傳

所以,現在的問題是如何在PHP命令行

注意模擬這樣的:使用硒我們可以模擬webform ..但我需要另一種選擇。

回答

7

你基本上需要讓你的代碼更加可測試。分解它,以便您可以測試通過HTTP與其他代碼分開上傳文件的簡單操作。 move_uploaded_file的主要用途是放入額外的安全停止位置,因此您不能欺騙其他文件,move_uploaded_file只需確保該文件已上載到同一個請求中,然後再移動它。您也可以簡單地使用rename來移動文件。因此,將應用程序分解爲一個代表並封裝當前HTTP請求的對象,其中包括使用is_uploaded_file檢查上傳的文件。一旦驗證通過,您可以使用rename而不是move_uploaded_file。在你的測試中,你可以嘲笑Request對象並測試你的其他代碼。

你也可以簡單地move_uploaded_file mockable,例如像這樣:

class Foo { 

    public function do() { 
     ... 
     $this->move_uploaded_file($from, $to); 
     ... 
    } 

    protected function move_uploaded_file($from, $to) { 
     return move_uploaded_file($from, $to); 
    } 

} 

在您的測試,你可以擴展/嘲笑類並覆蓋Foo::move_uploaded_file總是return true,例如。

0

你可以在命令行做文件上傳與cURL

curl --form [email protected] http://localhost/upload.php 

input-name而在HTML輸入字段的名稱正常使用,filename是路徑和文件名上傳 - 請記住把它們放在引號中,或者如果它們包含一些特殊字符就會轉義。

但是,這顯然仍然需要從網絡服務器運行腳本,顯然這不是您想要的,所以請參閱How can I write tests for file upload in PHP?瞭解如何使用PHPUnit測試文件上載。

2

如果要使用PHPUnit測試文件上傳而不嘲笑實際的move_uploaded_file檢查,可以使用測試用例,PHPUnit可以執行該測試用例,以便模擬Web請求。

基本上你創建一個.phpt文件看起來像這樣:

獨立例如:uploadTest.phpt

--TEST-- 
Example test emulating a file upload 
--POST_RAW-- 
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryfywL8UCjFtqUBTQn 

------WebKitFormBoundaryfywL8UCjFtqUBTQn 
Content-Disposition: form-data; name="file"; filename="example.txt" 
Content-Type: text/plain 

Qafoo provides quality assurance support and consulting 

------WebKitFormBoundaryfywL8UCjFtqUBTQn 
Content-Disposition: form-data; name="submit" 

Upload 
------WebKitFormBoundaryfywL8UCjFtqUBTQn-- 
--FILE-- 
<?php 

var_dump(is_uploaded_file($_FILES['file']['tmp_name'])); 

?> 
--EXPECT-- 
bool(true) 

使用phpunit uploadTest.phpt


對於充分說明運行檢查出的博客文章描述細節:

http://qafoo.com/blog/013_testing_file_uploads_with_php.html

另外:There is working sample code over at github


更詳細的現實世界的例子:

--TEST-- 
Example test emulating a file upload 
--POST_RAW-- 
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryfywL8UCjFtqUBTQn 

------WebKitFormBoundaryfywL8UCjFtqUBTQn 
Content-Disposition: form-data; name="file"; filename="example.txt" 
Content-Type: text/plain 

Qafoo provides quality assurance support and consulting 

------WebKitFormBoundaryfywL8UCjFtqUBTQn 
Content-Disposition: form-data; name="submit" 

Upload 
------WebKitFormBoundaryfywL8UCjFtqUBTQn-- 
--FILE-- 
<?php 
require __DIR__ . '/UploadExample.php'; 

$upload = new UploadExample('/tmp'); 
$upload->handle('file'); 

var_dump(file_exists('/tmp/example.txt')); 
?> 
--EXPECT-- 
bool(true) 
+0

這個例子適合你嗎?我甚至無法從qa.php.net獲取簡單的'POST_RAW'示例來工作,並且不知道失敗是什麼。我在Xubuntu上運行PHP 5.3.10-1。 –

+0

@DavidHarkness我編輯了一個獨立的例子,很好地爲我工作的問題。使用PHPUnit 3.6和3.7的5.3&5.4 ubuntu。 – edorian

+0

PHPUnit 3.7.9跳過測試。有什麼方法可以確定它被跳過的原因嗎? –

3

這就是PHP Testing Framework(亢進症)來自於它安裝了PEAR並允許您。通過編寫.phpt文件並將其與run-phptpear run-tests <file.phpt>一起執行,將HTTP請求,I/O操作,文件上載等提供給PHP腳本。您也可以使用PhptTestCasePhptTestSuite來使用run them with PHPUnit

要模擬文件上傳,您需要使用--POST_RAW-- section和瀏覽器發送的相同數據。這是從PHP QAT網站上的例子:

重要:不幸的是,在其網站上的例子失敗沒有任何解釋。

is_uploaded_file.phpt

--TEST-- 
is_uploaded_file() function 
--CREDITS-- 
Dave Kelsey <[email protected]> 
--SKIPIF-- 
<?php if (php_sapi_name()=='cli') die('skip'); ?> 
--POST_RAW-- 
Content-type: multipart/form-data, boundary=AaB03x 

--AaB03x 
content-disposition: form-data; name="field1" 

Joe Blow 
--AaB03x 
content-disposition: form-data; name="pics"; filename="file1.txt" 
Content-Type: text/plain 

abcdef123456789 
--AaB03x-- 
--FILE-- 
<?php 
// uploaded file 
var_dump(is_uploaded_file($_FILES['pics']['tmp_name'])); 

// not an uploaded file 
var_dump(is_uploaded_file($_FILES['pics']['name'])); 

// not an uploaded file 
var_dump(is_uploaded_file('random_filename.txt')); 

// not an uploaded file 
var_dump(is_uploaded_file('__FILE__')); 

// Error cases 
var_dump(is_uploaded_file()); 
var_dump(is_uploaded_file('a', 'b')); 

?> 
--EXPECTF-- 
bool(true) 
bool(false) 
bool(false) 
bool(false) 

Warning: is_uploaded_file() expects exactly 1 parameter, 0 given in %s on line %d 
NULL 

Warning: is_uploaded_file() expects exactly 1 parameter, 2 given in %s on line %d 
NULL 

運行

pear run-tests --cgi=PHPCGI is_uploaded_file.phpt 

曼努埃爾Pichler的寫了一個例子,一個blog post,但它也將失敗。

1

就我個人而言,我喜歡上面給出的deceze的答案。

但是,另一種可能性是使用namespaces

此代碼位於Github

相關問題