当然,您应该编写一个测试用例,但您会认为该测试用例能将您的特定更改在条件从句的海洋中隔离起来吗?
测量路径复杂度
圈复杂度 是在我前面提到的那些研究期间开创的,它可以精确地测量路径复杂度。通过利用某一方法路由不同的路径,这一基于整数的度量可适当地描述方法复杂度。实际上,过去几年的各种研究已经确定:圈复杂度(或 CC)大于 10 的方法存在很大的出错风险。因为 CC 通过某一方法来表示路径,这是用来确定某一方法到达 100% 的覆盖率将需要多少测试用例的一个好方法。例如,以下代码(您可能记得本系列的第一篇文章中使用过它)包含一个逻辑缺陷:
清单 2. PathCoverage 有一个缺陷!
public class PathCoverage {
public String pathExample(boolean condition){
String value = null;
if(condition){
value = " " condition " ";
}
return value.trim();
}
}
作为响应,我可以编写一个测试,它将达到 100% 的行覆盖率:
清单 3. 一个测试产生完全覆盖!
import junit.Framework.TestCase;
public class PathCoverageTest extends TestCase {
public final void testPathExample() {
PathCoverage clzzUnderTst = new PathCoverage();
String value = clzzUnderTst.pathExample(true);
assertEquals("should be true", "true", value);
}
}
接下来,我将运行一个代码覆盖率工具,比如 Cobertura,并将获得如图 1 中所示的报告:
图 1. Cobertura 报告
哦,有点失望。代码覆盖率报告指示 100% 的覆盖率,但我们知道这是一个误导。
二对二
注意,清单 2 中的 pathExample() 方法有一个值为 2 的 CC(一个用于默认路径,一个用于 if 路径)。使用 CC 作为更精确的覆盖率测量尺度意味着第二个测试用例是必需的。在这里,它将是不进入 if 条件语句而采用的路径,如清单 4 中的 testPathExampleFalse() 方法所示:
清单 4. 沿着较少采用的路径向下
import junit.Framework.TestCase;
public class PathCoverageTest extends TestCase {
public final void testPathExample() {
PathCoverage clzzUnderTst = new PathCoverage();
String value = clzzUnderTst.pathExample(true);
assertEquals("should be true", "true", value);
}
public final void testPathExampleFalse() {
PathCoverage clzzUnderTst = new PathCoverage();
String value = clzzUnderTst.pathExample(false);
assertEquals("should be false", "false", value);
}
}
正如您可以看到的,运行这个新测试用例会产生一个令人讨厌的 NullPointerException。在这里,有趣的是我们可以使用圈复杂度而不是 使用代码覆盖率来找出这个缺陷。代码覆盖率指示我们已经在一个测试用例之后完成了此操作,但 CC 却会强迫我们编写额外的测试用例。不算太坏,是吧?
幸运的是,这里的测试中的方法有一个值为 2 的 CC。设想一下该缺陷被隐藏在 CC 为 102 的方法中的情况。祝您好运找到它!
图表上的 CC
Java 开发人员可使用一些开放源码工具来报告圈复杂度。其中一个这样的工具是 JavaNCSS,它通过检查 Java 源文件来确定方法和类的长度。此外,此工具还收集代码库中每个方法的圈复杂度。通过利用 Ant 任务或 Maven 插件配置 JavaNCSS,可以生成一个列出以下内容的 XML 报告:
- 每个包中的类、方法、非注释代码行和各种注释样式的总数。
- 每个类中非注释代码行、方法、内部类和 Javadoc 注释的总数。
- 代码库中每个方法的非注释代码行的总数和圈复杂度。
该工具附带了少量样式表,可以使用它们来生成总结数据的 HTML 报告。例如,图 2 阐述了 Maven 生成的报告:
图 2. Maven 生成的 JavaNCSS 报告
此报告中带有 Top 30 functions containing the most NCSS 标签的部分详细描述了代码库中最长的方法,顺便提一句,该方法几乎总是 与包含最大圈复杂度的方法相关联。例如,该报告列出了 DBInsertQueue 类的 updatePCensus() 方法,因为此方法的非注释行总数为 283,圈复杂度(标记为 CCN)为 114。
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!


