我该如何在PHP中编写文件上传测试?

16
我正在使用simpleTest来编写我的PHP测试。我正在编写一个文件上传插件,并想知道如何进行测试。
我想检查文件是否被正确上传到了正确的文件夹中,当需要时是否正确返回错误等。
如何模拟文件上传(通过$_FILES变量)?有什么问题我需要注意吗?
4个回答

28

我找到了一种替代方案。我用测试数据欺骗了$_FILES数组,在tmp/文件夹中创建了虚拟测试文件(文件夹是无关紧要的,但我尝试坚持默认设置)。

问题在于,is_uploaded_filemove_uploaded_file无法处理这些欺骗的项目,因为它们并不是真正通过POST上传的。 我所做的第一件事是将这些函数包装在我的插件中的自己的moveUploadedFileisUploadedFile中,以便我可以模拟它们并更改它们的返回值。

最后一件事是在测试时扩展该类并覆盖moveUploadedFile以使用rename而不是move_uploaded_file,并且将isUploadedFile覆盖为使用file_exists而不是is_uploaded_file


2
扩展这个答案,讲解如何模拟 move_uploaded_file 中文件移动的过程会非常有帮助。 - David Yell
@pixelastic,你能否给我们展示一下你的代码? - Magiranu
不幸的是,这个问题已经超过7年了,我不再拥有这段代码的访问权限(而且,自那时以来PHP版本已经更新了很多,我认为我的代码可能已经无法正常工作了)。 - pixelastic

9
根据文档,SimpleTest自1.0.1版本起支持文件上传测试。请参考SimpleTest官方文档了解更多信息。
File upload testing     Can simulate the input type file tag    1.0.1

我已经查看了他们网站上的示例,我认为你可以使用类似于以下内容的东西:

$this->get('http://www.example.com/');
$this->setField('filename', 'local path');
$this->click('Go');

将文件提交,然后使用常规的断言来检查上传是否按要求工作。但这只是一个猜测,因为我不熟悉SimpleTest,并且在他们的主页上找不到示例。你可能想去询问他们的支持论坛。

但基本上,测试表单上传文件并没有太多用处。这是经过试验和测试的浏览器行为。测试处理上传的代码更有意义。我不知道您如何实现您的FileUpload代码,但如果我必须实现它,我会首先摆脱对$_FILES数组的依赖关系。创建一个FileRequest类,您可以将$_FILES数组传递给它。然后您可以从该类处理上传。这将允许您在没有实际上传文件的情况下测试功能。只需相应地设置您的FileRequest实例即可。您甚至可以使用vfsStreamWrapper模拟文件系统,因此您甚至不需要实际文件。


我希望能够测试我的插件的小部分。进行整个获取请求无法提供我所需的详细级别。 - pixelastic

5
你可以使用例如curl扩展以编程方式生成文件上传。
由于这需要PHP在Web服务器下运行,因此它不太适合作为单元测试。因此,最好的方法是使用PHPT测试,并在--POST_RAW--部分填充数据。
如果您不知道要在--POST_RAW--中放什么,请尝试安装TamperData Firefox扩展程序,在Firefox中进行文件提交,然后将数据从右侧复制粘贴过来即可。

正如你所说,cURL并不适合进行单元测试。我阅读了PHPT文档,认为这可能是更好的解决方案。不幸的是,我没有成功地让它工作...最终我找到了另一个解决方案(请参见我的答案)。 - pixelastic
我也尝试使用PHPT和--POST_RAW--,但是无法使其工作,如此文档所述:https://dev59.com/WlTTa4cB1Zd3GeqPqkHU - Ian

-2

对于单元测试(与功能测试相反),请尝试将文件(短文本文件)上传到测试页面,并使用var_dump($_FILES)var_dump($_POST)。然后您就知道该如何填充它们(或您的模拟对象)。


4
is_uploaded_file 仍会失败。 - Jon Skarpeteig
但是为什么?is_uploaded_file()在寻找什么?这不能轻松地进行模拟,有点愚蠢。 - dland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接