php - 我如何获得 php 代码覆盖率来运行 phpt 测试用例?

标签 php file-upload phpunit code-coverage phpt

我有一个运行产品组件测试的测试环境。我发现最近很难测试并成功模拟 php 的 is_uploaded_file()move_uploaded_file() 但经过大量搜索和研究后,我找到了 PHPT。这真的对我测试这些方法和文件上传的期望有很大帮助。这不是关于文件上传的问题,而是如何将 phpt 测试用例集成到基本的 phpunit 测试用例中,以便代码覆盖率也将针对正在测试的方法运行。下面是一些代码摘录:

文件.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');

    }

}

所以一切正常。但我似乎无法了解我正在测试的传输方法。请问有人能帮帮我吗?

编辑:我的覆盖命令如下所示:

@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%

最佳答案

由于 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 文件之外,您可以轻松访问配置文件或添加其他逻辑。

关于php - 我如何获得 php 代码覆盖率来运行 phpt 测试用例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5622437/

相关文章:

php - 如何从mysql数据库中删除缩略图

php - 如何 : Drupal File Upload Form

php - 使用带有未知数量参数的bind_parameters

php - MySQL 查询总是得到相同的结果

php - 无法卸载旧版本的 phpunit

Laravel 单元测试自动依赖注入(inject)不起作用?

c# - 如何使用 Web 表单上传个人资料图片

file-upload - 上传的文件(图片)是否应该允许有空格和非英文字符?

asp.net - AjaxFileUpload 回发 false

unit-testing - 如何解决此错误 : "Class PHPUnit_Extensions_SeleniumTestCase could not be found"