圈复杂度和代码覆盖率
(转载请注明来源于金庆的专栏)
100%代码覆盖率的单元测试并不代表是足够的测试,下面是一个例子:
int foo(bool isOK)
{
const int ZERO = 0;
int* pInt = NULL;
if (isOk)
{
pInt = &ZERO;
}
return *pInt;
}
如果仅仅测试一种情况:
foo(true);
结果是,测试通过,并具有100%的代码覆盖率。但我们知道foo(false);就会失败。
这里就要引入圈复杂度(Cyclomatic Complexity,CC)的概念。
圈复杂度是一种度量方法,由 Thomas McCabe 于 1975 年定义。
圈复杂度是一个方法中执行路径的数量。
起始CC从 1 开始。每一个条件,如 if、switch、while 和 for 语句,都被分配一个 1 值和异常路径。
一个方法的 CC 表明了它的复杂度。
以上foo()的CC为2,所以至少需要2个单元测试路径。
幸运的是,foo()的CC仅为2。
设想一下如果该缺陷被隐藏在 CC 为 102 的方法中,祝您好运找到它!
可使用一些开放源码工具来报告圈复杂度。C++可用Cppncss.
Cppncss是度量c++代码复杂度的工具,可度量函数级、文件级、工程级的复杂度。
可运行在windows(需要cygwin)及linux上。
参考:
追求代码质量: 监视圈复杂度 ( http://www.ibm.com/developerworks/cn/java/j-cq03316/ )
C++代码复杂度度量工具cppncss ( http://www.51testing.com/?uid-13997-action-viewspace-itemid-202260 )