PHPUnit和C.R.A.P指数
我使用的是php undercontrol,代码浏览器会在每个setter/getter上报告一些无用的索引错误,例如这样的代码PHPUnit和C.R.A.P指数,php,phpunit,metrics,phpundercontrol,Php,Phpunit,Metrics,Phpundercontrol,我使用的是php undercontrol,代码浏览器会在每个setter/getter上报告一些无用的索引错误,例如这样的代码 public function getFoo() { return $this->_foo; } 单元测试涵盖了getter/setter,因为没有if/for/switch/foreach,所以复杂性为零。那为什么我的代码的垃圾索引是1 PS:自我回答可能是因为复杂度为零,但我的主要问题是,每个getter/setter都会因为CRAP索引生成一个警
public function getFoo()
{
return $this->_foo;
}
单元测试涵盖了getter/setter,因为没有if/for/switch/foreach,所以复杂性为零。那为什么我的代码的垃圾索引是1
PS:自我回答可能是因为复杂度为零,但我的主要问题是,每个getter/setter都会因为CRAP索引生成一个警告,所以无论如何,是否有必要告诉phpunit/php代码覆盖率,使复杂度为0的函数的CRAP等于0。这真的是一个警告吗?通常,警告的阈值设置为远高于1(可能在30左右)。有一个很好的SO帖子展示了这个数字是如何计算的。在我的phpunit设置中,似乎有一些硬编码的值是30 根据CRAP索引的创建者的说法: “C.R.A.p.(变更风险分析和预测)指数旨在分析和预测维护现有代码体所需的工作量、痛苦和时间。”
最小垃圾数是100%覆盖率代码的圈复杂度。这种想法是,对复杂代码的更改比对简单代码的更改更容易产生问题。最低的垃圾分数是1,而不是0。这是因为CRAP的算法是
CRAP(m) = comp(m)^2 * (1 – cov(m)/100)^3 + comp(m)
函数的最小圈复杂度(comp)值为1。所以问题不在phpunit中,而是将垃圾1标记为问题的任何东西
一般来说,您希望将垃圾阈值设置在5左右,任何更低的地方,您也可以只使用一个简单的代码覆盖率度量(并以100%为准),因为复杂性因素几乎不起作用。大于等于30意味着任何测试都不能使您的方法不糟糕
圈复杂度通常可以手工计算(但有不止一个定义):
- 为函数调用添加1点
- 为每个循环添加1点
- 每个分支加1分
垃圾只是一个指标。就其本身而言,它与“一根绳子有多长?”一样有用,除了是一个答案不确定的问题外,它也是一个答案不确定的问题 如果你知道它在衡量什么,那么你可以把它作为复杂性的一个非常基本的指标。为了更好地利用它,您需要一点比较实现的经验。在这之后,理想情况下,您希望在同一事物的实现之间进行比较。在此之后,您需要深入了解正在测试的代码,如果您这样做,您的洞察力可能会比废话分数更好 它越高,在一些方面改进它的可能性就越高,例如可测试性(包括效率)和变更点。然而,直到超过8000或9000的分数,某件东西成为绝对垃圾的可能性才开始接近确定性。处理解析后的XML文档中的节点以实现一个无法以任何决定性方式改进的函数这样的基本功能,可以很容易地将复杂度提高到数百个,同时也非常好 这有点像花钱。为了某个特定的目的,你可能需要花费最少的钱。它可能是一百万,也可能是一千,但不管目的是什么,我们倾向于认为支出越高,就越有可能是过度的。但也许它需要很高,也许你在买游艇。天真地强迫数字下降不仅仅是在另一个方向上犯同样的错误,而且是真正危险的。71人在格伦菲尔铁塔被烧死或窒息,这是因为他们认为单凭数字就能取得最好的成就,这是一个灾难性的思维错误 您不应该认为减少垃圾会提高可测试性或可维护性。很多时候,高垃圾只是报告强制性复杂性的度量。你可以从技术上减少废话,玩数字游戏,同时降低可测试性、可维护性和可读性。你只能通过实际改进来改进这些东西。废话甚至不是衡量进步的可靠标准。有时,改善后,垃圾可能会下降。有时它可能会上升。度量游戏的问题在于,人们通常只是转移问题或隐藏被度量的事物作为复杂性的指标 一个常见的例子是使用映射而不是switch或if语句。我倾向于自己虔诚地这样做。然而,我们忘记了我们正在取代复杂性。在这种情况下,我们可以,我们有一个与地图实用程序,维护和可依赖的图书馆。如果将该映射函数与几个If语句进行比较,那么对复杂性的总体度量将是非常重要的。当您没有这样一个实用程序可供使用时,您需要非常小心如何降低复杂性。例如,如果您试图完全消除if语句和For循环,我祝您好运 如果可以提高测试的速度,圈复杂度确实会很好地反映出来。这非常适用于函数中有两个if语句的情况。如果第二个所依赖的状态因第一个是否匹配而不同,则必须冗余运行第一个(4次而不是2次)。当您经常组合代码时,可能的排列会非线性增加。如果有八个函数接受布尔值并返回布尔值,则可以单独测试每个函数,以获得8次2(布尔值有两个可能的输入值)测试(16次测试)。但是,如果将所有这些功能组合在一起,则可能有256种不同的输入组合。圈复杂度有助于指出可能的情况 它还提供了一些关于函数时间参数的测试数量指示。如果你有一个函数