如何在php命令行中模拟文件上传

时间:2012-11-26 11:37:57

标签: phpunit php

我是PHPUnit测试框架的新手。

我们知道PHP的move_uploaded_file()函数在通过http POST方法上传文件之前不起作用

所以,问题是如何在PHP命令行中模拟这个

注意:使用硒我们可以模拟webform ..但我需要另一种选择。

5 个答案:

答案 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)

就个人而言,我喜欢上面deceze给出的答案。

然而,另一种可能性是使用namespaces

此代码位于Github

答案 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测试文件上载的方法。