过滤不需进行单元测试的包和类
[size=1.166em]针对项目中不需进行单元测试的包和类,我们可以利用 POM 文件中 Cobertura 的标注 (instrument) 设置,对相应的包和类进行剔除 (exclude) 或筛选 (include),使之不体现在覆盖率报告中,去除它们对整个覆盖率的影响,从而使报告更具针对性。其基本 POM 标签设置及解析如清单 3 中所示。清单 3. POM 中剔除包和类的设置示例[size=12.727272033691406px] exs/res/process/egencia/Mock*.class exs/res/process/test/**/*Test.class clean
[size=1.166em]通过在配置文件中使用 Include 与 Exclude,可以显式地指定哪些包和类被列入单元测试的统计范围,哪些包和类被剔除在此范围之外。正则表达式支持丰富的匹配条件,可以满足大多数项目对单元测试范围的要求。以上代码将 exs.res.process.egencia 下面所有的名称 Mock 开头的类,以及 exs.res.process.egencia.test 包下面以 Test 结尾的类都剔除在测试范围以外。在使用这种配置之后,代码整体的范围被缩小,因此在被覆盖到的代码数量不变的基础上,整个代码覆盖率会较以前提高。输出结果如图 2 所示。图 2. 包、类过滤效果
过滤类中的函数
[size=1.166em]最新版本中的 Cobertura 只能支持到类级别的过滤,而对于类中方法的过滤是不支持的。因此我们需要通过修改 Cobertura 源码,使 Cobertura 支持对类中方法的过滤。
[size=1.166em]对 Cobertura 及其插件改动所依据的主要原理是 : 修改 Cobertura-maven-plugin 项目中的 InstrumentationTask 类,增加 Ignoretrival,IgnoreMethod 等新增 POM 参数。配制正则表达式,修改 Cobertura 核心,在标注(instrumentation) 阶段遍历函数名时,检测函数名是否匹配传入的正则表达式,过滤函数体代码,从而把这些函数代码排除在代码覆盖统计之外,节省开发人员对这类代码的测试精力。
[size=1.166em]清单 4 至清单 6 是对 Cobertura 的几处核心改动,仅供读者参考。清单 4. 对 Cobertura 核心代码的改动之一[size=12.727272033691406px] private void checkForTrivialSignature() { Type[] args = Type.getArgumentTypes(myDescriptor); Type ret = Type.getReturnType(myDescriptor); if (myName.equals("")) { isInit = true; mightBeTrivial = true; return; } if (myName.startsWith("set") && args.length == 1 && ret.equals(Type.VOID_TYPE)) { isSetter = true; mightBeTrivial = true; return; } if ((myName.startsWith("get") || myName.startsWith("is") || myName.startsWith("has")) && args.length == 0 && !ret.equals(Type.VOID_TYPE)) { isGetter = true; mightBeTrivial = true; return; } }
清单 5. 对 Cobertura Maven plugin 的改动[size=12.727272033691406px]private String ignoreMethodAnnotation;private String ignoreTrivial;/** * 创建一个新的对象,用于进行配置。 */ public ConfigInstrumentation() /** * * 该方法用于设置annotation的名字以用于过滤类内部的方法 * @param ignoreMethodAnnotation */public void setIgnoreMethodAnnotation(String ignoreMethodAnnotation) { this.ignoreMethodAnnotation = ignoreMethodAnnotation;}public String getIgnoreTrivial() { return ignoreTrivial;}/** * 该方法用于标识测试类中的方法是否无关紧要不需要测试。 * @param ignoreTrivial */public void setIgnoreTrivial(String ignoreTrivial) { this.ignoreTrivial = ignoreTrivial;}
清单 6. POM 文件中使用修改后的 Cobertura 过滤类中的方法[size=12.727272033691406px] org.codehaus.mojo cobertura-maven-plugin 2.5.2 *main* true
[size=1.166em]以上修改都完成之后, 就可以运行“mvn:site”命令得到报告。图 4 是使用没有被修改的 Cobertura 产生的结果报告,无函数过滤效果。图 5 是使用被修改后的 Cobertura 产生的结果报告,可以从中看出,几个 set 与 get 方法已被排除在统计范围之外。图 4. 无函数名过滤效果
图 5. 增加函数过滤效果