我是PHPUnit测试框架的新手。
我们知道PHP的move_uploaded_file()
函数在通过http POST方法上传文件之前不起作用
所以,问题是如何在PHP命令行中模拟这个
注意:使用硒我们可以模拟webform ..但我需要另一种选择。
答案 0 :(得分:7)
您基本上需要使代码更易于测试。将其分解,以便您可以测试通过HTTP分别从其余代码上传文件的简单操作。 move_uploaded_file
的主要用途是添加额外的安全性停止,以便您不会被诱骗移动其他文件,move_uploaded_file
只需确保文件已在同一请求中上传,然后移动它。您也可以使用rename
简单地移动文件。因此,请断开您的应用程序以使用一个Request
对象来表示并封装当前的HTTP请求,包括使用is_uploaded_file
检查上载的文件。验证完成后,您可以使用rename
代替move_uploaded_file
。在测试中,您可以模拟Request
对象并测试其他代码。
你也可以简单地使move_uploaded_file
模仿,例如:
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
。
答案 1 :(得分:3)
这是PHP Testing Framework(PHPT)的用武之地。它与PEAR一起安装,允许您通过编写{{}将HTTP请求,I / O操作,文件上载等提供给PHP脚本。 1}}文件并使用run-phpt
或.phpt
执行。您还可以run them with PHPUnit使用pear run-tests <file.phpt>
和PhptTestCase
。
要模拟文件上传,您需要使用浏览器发送的相同数据的--POST_RAW--
section。这是PHP QAT站点的示例:
重要说明:不幸的是,他们网站上的示例在没有任何解释的情况下失败。
<强> is_uploaded_file.phpt 强>
PhptTestSuite
<强>运行强>
--TEST--
is_uploaded_file() function
--CREDITS--
Dave Kelsey <d_kelsey@uk.ibm.com>
--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
Manuel Pichler在blog post中写了一个例子,但也失败了。
答案 2 :(得分:2)
如果你想使用PHPUnit来测试文件上传而不模拟实际的move_uploaded_file
检查,你可以使用.phpt
测试用例,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)
答案 3 :(得分:1)
答案 4 :(得分:0)
您可以使用cURL从命令行执行文件上传:
curl --form input-name=@filename http://localhost/upload.php
input-name
是通常使用的HTML中输入字段的名称,filename
是要上传的文件的路径和名称 - 请记住将它们放在引号中或转义特殊字符(如果它们)包含一些。
但是,这显然仍然需要从Web服务器运行脚本,显然这不是您想要的,所以请参阅How can I write tests for file upload in PHP?了解使用PHPUnit测试文件上载的方法。