我有一个运行产品组件测试的测试环境。我发现最近很难测试并成功模拟php的is_uploaded_file()
和move_uploaded_file()
,但经过大量的搜索和研究后,我遇到了PHPT。这对测试这些方法和文件上传期望有很大帮助。这不是关于文件上传的问题,而是如何将phpt测试用例集成到基本的phpunit测试用例中,以便代码覆盖也将针对正在测试的方法运行。以下是一些代码提取:
files.php
class prFiles
{
// Instance methods here not needed for the purpose of this question
// ......
public function transfer(array $files, $target_directory,
$new_filename, $old_filename = '')
{
if ( (isset($files['file']['tmp_name']) === true)
&& (is_uploaded_file($files['file']['tmp_name']) === true) )
{
// Only check if old filename exists
if ( (file_exists($target_directory . '/' . $old_filename) === true)
&& (empty($old_filename) === false) )
{
unlink($target_directory . $old_filename);
}
$upload = move_uploaded_file(
$files['file']['tmp_name'],
$target_directory . '/' . $new_filename
);
if ( $upload === true )
{
return true;
}
else
{
return false;
}
}
return false;
}
}
file_upload_test.phpt
--TEST--
Test the prFiles::transfer() the actual testing of the file uploading.
--POST_RAW--
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryfywL8UCjFtqUBTQn
------WebKitFormBoundaryfywL8UCjFtqUBTQn
Content-Disposition: form-data; name="file"; filename="test.txt"
Content-Type: text/plain
This is some test text
------WebKitFormBoundaryfywL8UCjFtqUBTQn
Content-Disposition: form-data; name="submit"
Upload
------WebKitFormBoundaryfywL8UCjFtqUBTQn--
--FILE--
<?php
require_once dirname(__FILE__) . '/../../../src/lib/utilities/files.php';
$prFiles = prFiles::getInstance()->transfer(
$_FILES,
dirname(__FILE__) . '/../_data/',
'test.txt'
);
var_dump($prFiles);
?>
--EXPECT--
bool(true)
UtilitiesFilesTransferTest.php
class UtilitiesFilesTransferTest extends PHPUnit_Extensions_PhptTestCase
{
/**
* Constructs a new UtilitiesFilesTransferTest.
*
*/
public function __construct()
{
parent::__construct(dirname(__FILE__) . '/_phpt/file_upload_test.phpt');
}
}
这样一切顺利。但我似乎无法覆盖我正在测试的传输方法。请有人帮帮我吗?
编辑:我的coverage命令如下所示:
@echo off
echo.
if not "%1"=="" goto location
goto default
:location
set EXEC=phpunit --coverage-html %1 TestSuite
goto execute
:default
set EXEC=phpunit --coverage-html c:\xampp\htdocs\workspace\coverage\project TestSuite
:execute
%EXEC%
答案 0 :(得分:1)
由于PhpUnit具有在单独进程中运行PHPT文件的自定义实现,因此使用PhpUnit获取代码覆盖集成可能会非常困难。
但是,如果您只需要覆盖(或者您愿意自己进行一些后期处理),那就变得非常简单。
以最简单的形式,您需要做的就是从PHPT文件调用xDebug。使用PHP_CodeCoverage(以及用于课程自动加载的Composer),您的--FILE--
部分可能如下所示:
--FILE--
<?php
/* autoload classes */
require __DIR__ . '/../../../vendor/autoload.php';
/* Setup and start code coverage */
$coverage = new \PHP_CodeCoverage;
$coverage->start('test');
/* run logic */
$prFiles = prFiles::getInstance()->transfer(
$_FILES,
__DIR__ . '/../_data/',
'test.txt'
);
var_dump($prFiles);
/* stop and output coverage data */
$coverage->stop();
$writer = new \PHP_CodeCoverage_Report_PHP;
$writer->process($coverage, __DIR__ . '/../../../build/log/coverage-data.php');
?>
所有收集的覆盖率数据都将放在coverage-data.php
文件中。
您可以加载此信息并将其与其他覆盖信息(例如从PhpUnit)合并,以您想要的任何格式创建输出。
覆盖逻辑可以放在一个单独的类中,只留下两行来添加到您想要涵盖的每个测试中:
--FILE--
<?php
/* autoload classes */
require __DIR__ . '/../../../vendor/autoload.php';
cover::start;
/* run logic */
$prFiles = prFiles::getInstance()->transfer(
$_FILES,
__DIR__ . '/../_data/',
'test.txt'
);
var_dump($prFiles);
cover::stop;
?>
和cover
班级:
<?php
class cover
{
private static $coverage;
/* Setup and start code coverage */
public static function start()
{
self::$coverage = new \PHP_CodeCoverage;
/* Make sure this file is not added to the coverage data */
$filter = self::$coverage->filter();
$filter->addFileToBlacklist(__FILE__);
self::$coverage->start('test');
}
/* stop and output coverage data */
public static function stop()
{
self::$coverage->stop();
$writer = new \PHP_CodeCoverage_Report_PHP;
$writer->process(self::$coverage, __DIR__ . '/../build/log/coverage-data.php');
}
}
由于覆盖逻辑位于PHPT文件之外,您可以轻松访问配置文件或添加其他逻辑。
答案 1 :(得分:-3)
我不明白为什么PHPUnit不会为您收集此覆盖数据。它可能与它如何使用(或不使用)XDebug有关。
您可以使用不依赖于PHPUNit或XDebug如何工作的测试覆盖率工具来解决这个问题。
我们的PHP Test Coverage将收集任何已被告知要跟踪的PHP脚本中的任何函数的测试覆盖率,无论该函数的执行方式如何。它可以毫无困难地提供有关PHPT调用的函数执行的覆盖数据。