2011-08-16 74 views
4

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

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

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

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

感谢长久......

+0

你可以发布你的测试吗? – vascowhite

回答

8

您只有意见的代码才是最重要的。如果代码覆盖率报告可能落到头尾,则块的右大括号将显示为可执行文件。寻找一个你没有真正测试的分支。

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

至于100%的代码覆盖率目标,我完全同意Bill的意见。对于我写的一些框架类,我会努力做到100%,但我知道这并不意味着我已经真正测试过每一种可能性。通常,当我发现自己努力工作以达到100%的覆盖率时,可能是强迫症踢入。:)

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

+0

谢谢大卫,你已经钉住了它。我真的很感谢Bill和edorian关于代码覆盖的观点,然而你对'堕落到最后'的评论将帮助我指出那些注入'不可测试'的位! –

+0

在这里添加一件事。当你使用帮助者方法改变控制流时,这种情况会发生很多,例如调用'exit()'或引发异常的方法。代码覆盖工具不知道该函数永远不会将控制权返回给调用者。我将通过PHPCC提交一个针对'@ neverReturns'方法注释的增强请求,但是我怀疑Sebastian会为此付出代价。 –

12

我是Zend框架的项目负责人,几年前,通过ZF 1.0的版本。我非常努力地提高所有组件的测试覆盖率,并且我们制定了一个策略,即组件必须具有一定的最低代码覆盖率,以便从孵化器中采纳到ZF中。

但是,您说得对,试图从所有类的测试中获得100%的代码覆盖率并不实际。 ZF的一些课程有100%的覆盖率,但对于这些,一个或多个以下内容是真实的:

  • 该课程非常简单。
  • 这些测试需要非凡的工作来编写。例如。复杂的设置代码来创建条件来锻炼所有不起眼的角落案例。看看我写的Zend_Db的单元测试!虽然强迫自己测试这些角落案例是有益的,因为我保证它会将您引导至需要修复的代码。
  • 该类必须被重构为更“可测试”。无论如何,这通常是件好事,因为最终得到的OO代码更好,耦合更少,静态元素更少等。请参阅Zend_Log的类和测试。

但是我们也意识到100%的代码覆盖率有时是人为的目标。尽管如此,测试套件可以达到较低的100%覆盖率。而一个达到100%覆盖率的测试套件并不一定能保证质量。

为以下功能获得100%的代码覆盖率将非常容易。但是我们测试了零除吗?

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

所以,你应该使用代码覆盖率为一体的测试指标,但不是终极目标。

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中没有任何内容可以阻止您正确测试这些内容

相关问题