1

在测试控制器时,我可以合法地实现 100% 的代码覆盖率,如下所示:

正确报告 100% 代码覆盖率的示例

控制器代码

<?php
App::uses('AppController', 'Controller');

class UsersController extends AppController {

    public function example($option = null) {
        if ($option == 'foo') {
            $some_var = 'hello';
        } elseif ($option == 'bar') {
            $some_var = 'goodbye';
        }

        $this->set(compact('option', 'some_var'));
    }
}

测试代码

<?php
App::uses('UsersController', 'Controller');

class UsersControllerTest extends ControllerTestCase {

    public function testExampleFoo() {
        $this->testAction('/users/example/foo');
        $this->assertEquals('hello', $this->vars['some_var']);
    }

    public function testExampleBar() {
        $this->testAction('/users/example/bar');
        $this->assertEquals('goodbye', $this->vars['some_var']);
    }
}

但是,我如何确定在我的视图中实现了 100% 的代码覆盖率?例如:

100% 代码覆盖率的错误报告示例

控制器代码

<?php
App::uses('AppController', 'Controller');

class UsersController extends AppController {

    public function example($option = null) {
        $this->set('option', $option);
    }
}

查看代码

<?php

if ($option == 'foo') {
    $some_var = 'hello';
} elseif ($option == 'bar') {
    $some_var = 'goodbye';
}

if (isset($some_var)) {
    echo $some_var;
}

测试代码

<?php
App::uses('UsersController', 'Controller');

class UsersControllerTest extends ControllerTestCase {

    public function testExampleFoo() {
        $result = $this->testAction('/users/example/foo', array('return' => 'view'));
        $this->assertEquals('hello', $result);
    }
}

请注意,上面的测试代码不会测试“/users/example/bar” URL,因此elseif永远不会测试视图。因此,即使 100% 的控制器代码经过测试,我实际上并没有达到 100% 的代码覆盖率(因为测试的视图代码不到 100%)。我能做些什么呢?

4

1 回答 1

2

为了回答标题中的问题,CakePHP 可以使用 XDebug提取测试的代码覆盖率。如果我没记错的话,它会将代码覆盖率渲染嵌入到测试套件中。

作为对您上面给出的示例的一般评论,恕我直言,我什至会在没有传递任何选项时测试控制器以确保它以预期的方式响应,即使它抛出异常也是如此。

更新

我很抱歉没有正确阅读@Nick 的问题。

据我所知,CakePHP 不会提高.ctp文件的代码覆盖率。然而,这并不意味着 XDebug 不会生成它,您可能可以使用您的 IDE(我使用具有工具的 PhpStorm)或 XDebug 本身来直接拉回代码覆盖率。当然,这并不能使测试像在 CakePHP 中单独使用测试套件那样顺利。

或者,您可以针对渲染的视图进行测试。根据文档,可以在测试操作时指定返回类型。因此,一种可能的解决方案是将viewcontents与预渲染文件进行比较。然而,这样做是有危险的,因为任何不可见的字符 ( '\n', '\r', '\t') 都可能导致断言失败,即使在逻辑上,目标和结果标记是相同的。

文档中的一个示例显示了如何使用正则表达式断言值,从而允许您检查文档的特定区域的有效性。您也可以使用 PHP 的DOM 类来遍历文档。

祝你好运!

更新 21:21 09/05/2013

CakePHP 的测试套件建立在 PHP 单元之上,而 PHP 单元又使用 XDebug 生成代码覆盖率。我查看了源代码并检查了BaseCoverageReport该类,发现运行测试所使用的任何框架文件都生成了覆盖范围,包括被测单元(例如您的控制器)。这向我表明,代码覆盖没有选择性地打开,它是为包括视图模板在内的所有文件生成的。话虽如此,我没有找到模板作为它为其生成代码覆盖率的文件之一。但是,我确实注意到没有为View该类生成代码覆盖率,这意味着没有渲染任何内容。正是在这一点上,我有点困惑,因为我想必须渲染一些东西才能访问vieworcontents控制器测试用例的属性。经过仔细检查,结果发现这些值是空的,所以我的设置似乎有问题。

我建议你做的是获得一个支持调试的开源 IDE,比如Eclipse 的 PHP 开发工具,并在你的代码中设置一个断点,并通过框架跟踪线程。这将使您更深入地了解在测试控制器时视图是如何呈现的,如果是这样,将有助于跟踪代码覆盖率。我个人会认为模板的代码覆盖率会非常有用,我很惊讶该功能不存在。如果您确实选择修改框架的源代码,则可能值得在 GitHub 中克隆 CakePHP,然后添加一个拉取请求,以便它们可以将您的更改合并到主分支中。

对不起,我帮不上什么忙,我尽力了!

于 2013-05-09T17:31:21.930 回答