首页 文章

如何使用PHPUnit获得100%的代码覆盖率

提问于
浏览
4

我正在编写Zend Framework应用程序并使用PHPUnit对其进行单元测试 . 总的来说,事情正在顺利进行,但是我有一个小的,但烦人的PHPUnit和代码覆盖问题 - 它有时会告诉我一个特定的行没有经过测试,我不知道如何强制它进行测试 .

例如,在下面的代码中,我启动了两个测试:一个带有GET请求,一个带有POST请求 . 测试通过,这一切都很好 . 但是,当我查看代码覆盖率时,它会向我显示“else”行未执行 .

public function editAction()
{        
    if ($request->isPost()) {
        // do actions related to POST
    } else {
        // do action related to GET
    }
}

有任何想法吗?作为一个侧面问题,您通常坚持单元测试,直到您获得100%的代码覆盖率?或者这不是很实用吗?

非常感谢......

3 回答

  • 12

    您只评论的代码才是最重要的 . 如果可以直到最后,块的右括号将在代码覆盖率报告中显示为可执行 . 寻找一个你实际上没有测试过的分支 .

    if ($request->isPost()) {
        if ($x < 5) {
            return '<';
        }
        elseif ($x > 5) {
            return '>';
        }
        // Do you have a test for $x == 5?
    }
    

    至于100%的代码覆盖率目标,我全心全意地同意比尔的意见 . 对于我写的一些框架类,我将努力做到100%,但我知道这并不意味着我已经真正测试了所有可能性 . 通常情况下,当我发现自己过于努力地实现100%的覆盖率时,可能就是强迫症开始了 . :)

    只是 . . . 一个 . . . 更多 . . . 测试 . . .

  • 3

    几年前,通过ZF 1.0的发布,我是Zend Framework的项目负责人 . 我努力提高所有组件的测试覆盖率,并且我们制定了一项策略,即组件必须具有一定的最小代码覆盖率才能从孵化器中采用到ZF中 .

    但是,你是对的,尝试从所有类的测试中获得100%的代码覆盖率并不实际 . ZF中的一些类具有100%的覆盖率,但对于这些类,以下一个或多个是真的:

    • 这堂课非常简单 .

    • 测试需要非凡的工作才能写出来 . 例如 . 复杂的设置代码,以创建条件来练习所有模糊的角落案例 . 看看我写的Zend_Db的单元测试!虽然它会引导您进入需要修复的代码 .

    • 该类必须重构为更多"testable" . 无论如何,这通常是一件好事,因为你最终得到更好的OO代码,耦合更少,静态元素更少等 . 请参阅Zend_Log的类和测试 .

    但我们也意识到100%的代码覆盖率有时是人为的目标 . 尽管如此,测试套件的棕褐色100%覆盖率仍然足够 . 确保达到100%覆盖率的测试套件并不一定能保证质量 .

    对于以下函数,获得100%的代码覆盖率非常容易 . 但是我们测试除以零吗?

    function div($numerator, $denominator) {
        return $numerator / $denominator;
    }
    

    因此,您应该使用代码覆盖率作为测试的一个指标,但不是最终目标 .

  • 8

    如果这就是你的测试,那么我会考虑你的测试looks like Matthew described

    class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase {
        // [...]
        public function testSomething()
        {
            $this->request
                 ->setMethod('POST')
                 ->setPost(array(
                     'username' => 'foobar',
                     'password' => 'foobar'
                 ));
            $this->editAction();
            // assertThatTheRightThingsHappend
        }
    }
    

    在这种情况下,我认为没有任何理由为什么不容易获得100%的代码覆盖率 .

    但是是的:测试Zend Framework控制器非常困难,在某些时候你要么必须非常努力地从控制器中获取所有的应用程序逻辑,要么只是忍受它 .

    同样的事情不适用于您的模型 . 即使在ZF应用程序中,这些应该非常容易测试 .

    代码覆盖所服务的目的是告诉您代码库的哪些部分甚至没有被执行 . 它不会使用@covers甚至可能对你说谎 . )

    简而言之:如果您拥有大型控制器并且不易改变架构,只需使用如此经过测试的控制器进行设置,但不要将相同的逻辑应用于您的模型 . ZF中的任何内容都无法正确测试这些内容

相关问题