PHPUnit的代码涵盖范围不包括执行的方法

时间:2019-03-22 22:32:04

标签: php phpunit code-coverage

对于可能错误使用术语,我深表歉意。

我目前正在尝试将单元测试应用到我的工作中,但是现在我遇到了一个问题,如果根本不存在的话。

在要测试的对象中,执行了一种方法,尽管该方法已执行且测试成功通过,但并未被代码覆盖范围标记为已测试。

我已经尝试过是由于方法的可见性(受保护)还是作为参数传递的回调,这可能是通过更改可见性和参数而导致此“错误”的,但这并没有似乎不是原因。

我使用以下设置

  • php-code-coverage 6.1.4
  • PHP 7.1.10
  • Xdebug 2.6.1
  • PHPUnit 7.5.7

以下代码部分调用了extend方法并传递了一个匿名函数。

$this->values[$key] = $this->extend($key, function ($previous, ContainerInterface $container) use ($extensionFactory) {
    return call_user_func($extensionFactory, $container, $previous);
});

这是执行上述方法的测试

public function testContainerRegistersExtensions()
{
    /** mocking provider... */

    $this->assertEquals(['foo', 'bar'], (new Container([$provider]))->get('value'));
}


在下面的图片代码片段中(如我所见)(我的名声不允许使用图像),该代码被标记为覆盖(绿色),但是该方法尽管不是在测试过程中执行的,extend不是(红色):

$this->values[$key] = $this->extend($key, function ($previous, ContainerInterface $container) use ($extensionFactory) {
    return call_user_func($extensionFactory, $container, $previous);
});
protected function extend($id, $callable)
{  
    $factory = $this->values[$id];

    $extended = function (ContainerInterface $container) use ($callable, $factory) {
    # if the entry to extend is not a callable, we pass it as is
    $previous = is_callable($factory) ? $factory($container) : $factory;
        return $callable($previous, $container);
    };

    $this->values[$id] = $extended;

    return $this->values[$id];
}


执行测试后的结果如下

PHPUnit 7.5.7 by Sebastian Bergmann and contributors.


Time: 260 ms, Memory: 6.00 MB

OK (11 tests, 12 assertions)

Generating code coverage report in HTML format ... done

现在我想知道我是否忘记了某件事或做错了什么,或者这可能是一个错误?

1 个答案:

答案 0 :(得分:0)

好像我找到了解决方案。有关注释的PHPUnit文档说:

  

@covers批注可以在测试代码中用于指定测试方法要测试的方法

PHPUnit 7.5 Documentation - Annotations

因此,如果我在PHPDoc中指定一个@covers标记,则还将覆盖相应的方法(并且仅覆盖实际执行的部分)。遗憾的是,这种情况不会自动发生,但这也许是故意的。


我的测试现在看起来像这样

/**
 * @covers \<Namespace>\Container::register
 * @covers \<Namespace>\Container::extend
 * @covers \<Namespace>\Container::get
 */
public function testContainerRegistersExtensions()
{
    /** mocking provider... */

    $this->assertEquals(['foo', 'bar'], (new Container([$provider]))->get('value'));
}