我是 PHPUnit 测试框架的新手。
我们知道move_uploaded_file()
PHP 的功能只有在通过 http POST 方法上传文件后才会起作用
所以,问题是如何在 PHP 命令行中模拟这个
注意:使用 selenium 我们可以模拟 webform .. 但我需要另一种选择。
您基本上需要使您的代码更具可测试性。将其分解,以便您可以将通过 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
为 always return true
。
这就是PHP 测试框架(PHPT) 的用武之地。它与 PEAR 一起安装,允许您通过编写文件并使用或.phpt
执行它来将 HTTP 请求、I/O 操作、文件上传等提供给 PHP 脚本。您还可以使用PHPUnit 运行它们和。run-phpt
pear run-tests <file.phpt>
PhptTestCase
PhptTestSuite
要模拟文件上传,您需要使用与浏览器发送的相同数据的--POST_RAW--
部分。这是来自 PHP QAT 站点的示例:
重要提示:不幸的是,他们网站上的示例没有任何解释就失败了。
is_uploaded_file.phpt
--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
跑步
pear run-tests --cgi=PHPCGI is_uploaded_file.phpt
Manuel Pichler 在博客文章中写了一个例子,但它也失败了。
如果您想使用 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)
您可以使用cURL从命令行上传文件:
curl --form input-name=@filename http://localhost/upload.php
input-name
是通常使用的 HTML 中输入字段的名称filename
,是要上传的文件的路径和名称 - 如果它们包含一些特殊字符,请记住将它们放在引号中或转义特殊字符。
但是,这显然仍然需要从网络服务器运行脚本,显然这不是您想要的,所以请参阅如何为 PHP 中的文件上传编写测试?有关使用 PHPUnit 测试文件上传的方法。