我正在编写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%的代码覆盖率?或者这不是很实用吗?
非常感谢......
答案 0 :(得分:12)
几年前,通过ZF 1.0的发布,我是Zend Framework的项目负责人。我努力提高所有组件的测试覆盖率,我们制定了一项政策,即组件必须具有一定的最小代码覆盖率才能从孵化器中采用到ZF中。
但是,你是对的,尝试从所有课程的测试中获得100%的代码覆盖率并不实际。 ZF中的一些类具有100%的覆盖率,但是对于这些类,以下一个或多个是真的:
但我们也意识到100%的代码覆盖率有时是人为的目标。尽管如此,测试套件的棕褐色100%覆盖率仍然足够。确保达到100%覆盖率的测试套件并不一定能确保质量。
为以下功能获得100%的代码覆盖率非常容易。但是我们测试除以零吗?
function div($numerator, $denominator) {
return $numerator / $denominator;
}
因此,您应该将代码覆盖率用作测试的一个指标,但不是最终目标。
答案 1 :(得分:8)
您只评论的代码才是最重要的。如果可以直到最后,块的右括号将在代码覆盖率报告中显示为可执行。寻找一个你实际上没有测试过的分支。
if ($request->isPost()) {
if ($x < 5) {
return '<';
}
elseif ($x > 5) {
return '>';
}
// Do you have a test for $x == 5?
}
至于100%的代码覆盖率目标,我全心全意地同意Bill的观点。对于我写的一些框架类,我将努力做到100%,但我知道这并不意味着我已经真正测试了所有可能性。通常情况下,当我发现自己过于努力地实现100%的覆盖率时,可能就是强迫症开始了。:)
只是。 。 。一个。 。 。更多 。 。 。测试。 。
答案 2 :(得分:3)
如果这就是你的测试,那么我会考虑你的测试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中没有任何内容阻止您正确测试这些