注册通行证 用户名 密码
  • 文章投稿
  • 博客
  • 论坛
  • 设为首页
  • 加入收藏
jztop.com网络技术
  • 首页
  • | iT新闻
  • | 操作系统
  • | 组网建网
  • | 网络安全
  • | 程序开发
  • | 办公一族
  • | 工具软件
  • | 网页制作
  • | 多媒体制作
  • | 网吧技术
  • | 服务器
  • | 专题教程
Vista | 软件评测 | 系统备份 | 优化 | 进程 | 聊天 | 病毒 | Linux | 黑客 | 防火墙 | 数据库 | Web开发 | Java | Word | 游戏 | 32位开发 | 移动开发
当前位置:首页 > 程序开发 > 数据库 > Oracle 内容正文:追求代码质量: 不要被覆盖报告所迷惑

追求代码质量: 不要被覆盖报告所迷惑

发布时间:2006-03-10 15:35:25 来源:ibm 网友评论 0 条
  测试覆盖工具对单元测试具有重要的意义,但是经常被误用。这个月,Andrew Glover 会在他的新系列 —— 追求代码质量 中向您介绍值得参考的专家意见。第一部分深入地介绍覆盖报告中数字的真实含义。然后他会提出您可以尽早并经常地利用覆盖来确保代码质量的三个方法。

  您还记得以前大多数开发人员是如何追求代码质量的吗。在那时,有技巧地放置 main() 方法被视为灵活且适当的测试方法。经历了漫长的道路以后,现在自动测试已经成为高质量代码开发的基本保证,对此我很感谢。但是这还不是我所要感谢的全部。Java? 开发人员现在拥有很多通过代码度量、静态分析等方法来度量代码质量的工具。我们甚至已经设法将重构分类成一系列便利的模式!

  所有的这些新的工具使得确保代码质量比以前简单得多,不过您还需要知道如何使用它们。在这个系列中,我将重点阐述有关保证代码质量的一些有时看上去有点神秘的东西。除了带您一起熟悉有关代码质量保证的众多工具和技术之外,我还将为您说明:
  • 定义并有效度量最影响质量的代码方面。
  • 设定质量保证目标并照此规划您的开发过程。
  • 确定哪个代码质量工具和技术可以满足您的需要。
  • 实现最佳实践(清除不好的),使确保代码质量及早并经常地 成为开发实践中轻松且有效的方面。
  在这个月,我将首先看看 Java 开发人员中最流行也是最容易的质量保证工具包:测试覆盖度量。

  谨防上当

  这是一个晚上鏖战后的早晨,大家都站在饮水机边上。开发人员和管理人员们了解到一些经过良好测试的类可以达到超过 90% 的覆盖率,正在高兴地互换着 NFL 风格的点心。团队的集体信心空前高涨。从远处可以听到 “放任地重构吧” 的声音,似乎缺陷已成为遥远的记忆,响应性也已微不足道。但是一个很小的反对声在说:

  女士们,先生们,不要被覆盖报告所愚弄。

  现在,不要误解我的意思:并不是说使用测试覆盖工具是愚蠢的。对单元测试范例,它是很重要的。不过更重要的是您如何理解所得到的信息。许多开发团队会在这儿犯第一个错。

  高覆盖率只是表示执行了很多的代码,并不意味着这些代码被很好地 执行。如果您关注的是代码的质量,就必须精确地理解测试覆盖工具能做什么,不能做什么。然后您才能知道如何使用这些工具去获取有用的信息。而不是像许多开发人员那样,只是满足于高覆盖率。

  测试覆盖度量

  测试覆盖工具通常可以很容易地添加到确定的单元测试过程中,而且结果可靠。下载一个可用的工具,对您的 Ant 和 Maven 构建脚本作一些小的改动,您和您的同事就有了在饮水机边上谈论的一种新报告:测试覆盖报告。当 foo 和 bar 这样的程序包令人惊奇地显示高 覆盖率时,您可以得到不小的安慰。如果您相信至少您的部分代码可以保证是 “没有 BUG” 的,您会觉得很安心。但是这样做是一个错误。

  存在不同类型的覆盖度量,但是绝大多数的工具会关注行覆盖,也叫做语句覆盖。此外,有些工具会报告分支覆盖。通过用一个测试工具执行代码库并捕获整个测试过程中与被 “触及” 的代码对应的数据,就可以获得测试覆盖度量。然后这些数据被合成为覆盖报告。在 Java 世界中,这个测试工具通常是 JUnit 以及名为 Cobertura、Emma 或 Clover 等的覆盖工具。

  行覆盖只是指出代码的哪些行被执行。如果一个方法有 10 行代码,其中的 8 行在测试中被执行,那么这个方法的行覆盖率是 80%。这个过程在总体层次上也工作得很好:如果一个类有 100 行代码,其中的 45 行被触及,那么这个类的行覆盖率就是 45%。同样,如果一个代码库包含 10000 个非注释性的代码行,在特定的测试运行中有 3500 行被执行,那么这段代码的行覆盖率就是 35%。

  报告分支覆盖 的工具试图度量决策点(比如包含逻辑 AND 或 OR 的条件块)的覆盖率。与行覆盖一样,如果在特定方法中有两个分支,并且两个分支在测试中都被覆盖,那么您可以说这个方法有 100% 的分支覆盖率。

  问题是,这些度量有什么用?很明显,很容易获得所有这些信息,不过您需要知道如何使用它们。一些例子可以阐明我的观点。

  代码覆盖在活动

  我在清单 1 中创建了一个简单的类以具体表述类层次的概念。一个给定的类可以有一连串的父类,例如 Vector,它的父类是 AbstractList,AbstractList 的父类又是 AbstractCollection,AbstractCollection 的父类又是 Object:

清单 1. 表现类层次的类
 package com.vanward.adana.hierarchy; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class Hierarchy {   private Collection classes;   private Class baseClass;   public Hierarchy() {     super();     this.classes = new ArrayList();   }   public void addClass(final Class clzz){     this.classes.add(clzz);   }   /**    * @return an array of class names as Strings    */   public String[] getHierarchyClassNames(){     final String[] names = new String[this.classes.size()];             int x = 0;     for(Iterator iter = this.classes.iterator(); iter.hasNext();){        Class clzz = (Class)iter.next();        names[x++] = clzz.getName();     }             return names;   }   public Class getBaseClass() {     return baseClass;   }   public void setBaseClass(final Class baseClass) {     this.baseClass = baseClass;   } } 

  正如您看到的,清单 1 中的 Hierarchy 类具有一个 baseClass 实例以及它的父类的集合。清单 2 中的 HierarchyBuilder 通过两个复制 buildHierarchy 的重载的 static 方法创建了 Hierarchy 类。

清单 2. 类层次生成器
 package com.vanward.adana.hierarchy; public class HierarchyBuilder {     private HierarchyBuilder() {     super();     }   public static Hierarchy buildHierarchy(final String clzzName)      throws ClassNotFoundException{       final Class clzz = Class.forName(clzzName, false,            HierarchyBuilder.class.getClassLoader());               return buildHierarchy(clzz);   }   public static Hierarchy buildHierarchy(Class clzz){     if(clzz == null){       throw new RuntimeException("Class parameter can not be null");     }     final Hierarchy hier = new Hierarchy();     hier.setBaseClass(clzz);     final Class superclass = clzz.getSuperclass();     if(superclass !=        null && superclass.getName().equals("java.lang.Object")){        return hier;      }else{              while((clzz.getSuperclass() != null) &&            (!clzz.getSuperclass().getName().equals("java.lang.Object"))){              clzz = clzz.getSuperclass();              hier.addClass(clzz);        }                 return hier;     }   }       } 

  现在是测试时间!

  有关测试覆盖的文章怎么能缺少测试案例呢?在清单 3 中,我定义了一个简单的有三个测试案例的 JUnit 测试类,它将试图执行 Hierarchy 类和 HierarchyBuilder 类:

清单 3. 测试 HierarchyBuilder!
 package test.com.vanward.adana.hierarchy; import com.vanward.adana.hierarchy.Hierarchy; import com.vanward.adana.hierarchy.HierarchyBuilder; import junit.framework.TestCase; public class HierarchyBuilderTest extends TestCase {      public void testBuildHierarchyValueNotNull() {              Hierarchy hier = HierarchyBuilder.buildHierarchy(HierarchyBuilderTest.class);      assertNotNull("object was null", hier);   }   public void testBuildHierarchyName() {              Hierarchy hier = HierarchyBuilder.buildHierarchy(HierarchyBuilderTest.class);      assertEquals("should be junit.framework.Assert",         "junit.framework.Assert",           hier.getHierarchyClassNames()[1]);         }   public void testBuildHierarchyNameAgain() {              Hierarchy hier = HierarchyBuilder.buildHierarchy(HierarchyBuilderTest.class);      assertEquals("should be junit.framework.TestCase",         "junit.framework.TestCase",           hier.getHierarchyClassNames()[0]);         }   } 

  因为我是一个狂热的测试人员,我自然希望运行一些覆盖测试。对于 Java 开发人员可用的代码覆盖工具中,我比较喜欢用 Cobertura,因为它的报告很友好。而且,Corbertura 是开放源码项目,它派生出了 JCoverage 项目的前身。



 1/3    1 2 3 ›› ›|
相关文章
    无相关信息
【评论】【收藏本文】【打印】【关闭】
上一篇文章:深入浅出组件编程之固有属性和事件属性
下一篇文章:开源软件在2006年如何走过?
讨论区
查看
已有 0 位对此新闻感兴趣的网友发表了看法
匿名发表
注册通行证 登陆
图文阅读推荐
Atlas快速入门之实战Atlas
Atlas快速入门之实战Atlas
.net页面间的参数传递简单实例
.net页面间的参数传递简单实例
推荐阅讯
  • IBM与Novel联手推新开源软件
  • Web2.0公司所要做的就是撕掉Web2.0标签
  • 程序开发:目前主流开发技术的分析和总结
  • 在Oracle的网络结构中解决连接问题
  • Spring事务处理及其AOP框架的内幕
  • 用AJAX开发智能Web应用程序之高级篇
  • 玩玩Spring之Rod Johnson与轮子理论
  • 看看如何在Struts应用中施展AJAX魔法
  • Oracle 10g R2特性之数据仓库和集成特性
  • Oracle数据库中索引的维护
阅读排行
  • 1..net页面间的参数传递简单实例
  • 2.VC++与Matlab混合编程之引擎操作详解
  • 3.Oracle数据库数据对象分析
  • 4.Eclipse3.2+Tomcat5.5.17+Oracle9配置
  • 5.Oracle数据库中索引的维护
  • 6.在Oracle的网络结构中解决连接问题
  • 7.Oracle数据安全面面观
  • 8.Oracle数据库的ORA-00257故障解决过程
  • 9.Oracle数据库备份与恢复的三种方法
  • 10.Oracle与SQL Server在企业应用中的比较
专题教程
  • 大话G游 专题:手机病毒揭密
  • ARP攻击防范与解决方案 路由故障处理手册
  • Picasa中文版_Picasa教程 专题:清除流氓软件
  • Firefox专题 seo搜索引擎优化专区
  • 重装Windows必知的事情 装机之必备软件大行动
病毒专杀栏
  • 杀毒软件反被病毒杀 连"救命"都不能喊
  • 金山ARP防火墙
  • 还原卡神话破灭“机器狗”病毒来势汹汹
  • cctv经济半小时:你的手机现在安全吗?
  • 新挂马方式开始流行 ARP挂马称雄局域网
  • 木马和病毒清除的通用解法
  • IP地址不再冲突 查找ARP攻击者元凶
  • 教你几招识别和防御Web网页木马
  • 分析:封杀BT只是暂时的止痛药
  • QQ爆危险漏洞,“QQ游戏邀请大盗”邀请你玩病
关于我们 | 诚聘英才 | 联系我们 | 版权声明 | 网站大事 | 网站地图 | 意见建议
CopyRight 2005-2007 Jztop.Com 版权所有 未经许可 请勿转载