AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > 软件工程

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

51自学网 http://www.51zixue.net

 

  Cobertura 的报告

  运行 Cobertura 这样的工具和运行您的 JUnit 测试一样简单,只是有一个用专门逻辑在测试时检查代码以报告覆盖率的中间步骤(这都是通过工具的 Ant 任务或 Maven 的目标完成的)。

  正如您在图 1 中看到的,HierarchyBuilder 的覆盖报告说明部分代码没有 被执行。事实上,Cobertura 认为 HierarchyBuilder 的行覆盖率为 59%,分支覆盖率为 75%。

图 1. Cobertura 的报告


  这样看来,我的第一次覆盖测试是失败的。首先,带有 String 参数的 buildHierarchy() 方法根本没有被测试。其次,另一个 buildHierarchy() 方法中的两个条件都没有被执行。有趣的是,所要关注的正是第二个没有被执行的 if 块。

  因为我所需要做的只是增加一些测试案例,所以我并不担心这一点。一旦我到达了所关注的区域,我就可以很好地完成工作。注意我这儿的逻辑:我使用测试报告来了解什么没有 被测试。现在我已经可以选择使用这些数据来增强测试或者继续工作。在本例中,我准备增强我的测试,因为我还有一些重要的区域未覆盖。

  Cobertura:第二轮

  清单 4 是一个更新过的 JUnit 测试案例,增加了一些附加测试案例,以试图完全执行 HierarchyBuilder:

清单 4. 更新过的 JUnit 测试案例
 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() { zo             Hierarchy hier = HierarchyBuilder.buildHierarchy(HierarchyBuilderTest.class);      assertEquals("should be junit.framework.TestCase",         "junit.framework.TestCase",           hier.getHierarchyClassNames()[0]);         }   public void testBuildHierarchySize() {              Hierarchy hier = HierarchyBuilder.buildHierarchy(HierarchyBuilderTest.class);      assertEquals("should be 2", 2, hier.getHierarchyClassNames().length);   }   public void testBuildHierarchyStrNotNull() throws Exception{     Hierarchy hier =         HierarchyBuilder.        buildHierarchy("test.com.vanward.adana.hierarchy.HierarchyBuilderTest");     assertNotNull("object was null", hier);   }   public void testBuildHierarchyStrName() throws Exception{             Hierarchy hier =         HierarchyBuilder.        buildHierarchy("test.com.vanward.adana.hierarchy.HierarchyBuilderTest");     assertEquals("should be junit.framework.Assert",        "junit.framework.Assert",         hier.getHierarchyClassNames()[1]);   }   public void testBuildHierarchyStrNameAgain() throws Exception{     Hierarchy hier =         HierarchyBuilder.        buildHierarchy("test.com.vanward.adana.hierarchy.HierarchyBuilderTest");     assertEquals("should be junit.framework.TestCase",        "junit.framework.TestCase",         hier.getHierarchyClassNames()[0]);         }   public void testBuildHierarchyStrSize() throws Exception{              Hierarchy hier =          HierarchyBuilder.         buildHierarchy("test.com.vanward.adana.hierarchy.HierarchyBuilderTest");      assertEquals("should be 2", 2, hier.getHierarchyClassNames().length);           }   public void testBuildHierarchyWithNull() {      try{        Class clzz = null;        HierarchyBuilder.buildHierarchy(clzz);        fail("RuntimeException not thrown");      }catch(RuntimeException e){}   } } 


  当我使用新的测试案例再次执行测试覆盖过程时,我得到了如图 2 所示的更加完整的报告。现在,我覆盖了未测试的 buildHierarchy() 方法,也处理了另一个 buildHierarchy() 方法中的两个 if 块。然而,因为 HierarchyBuilder 的构造器是 private 类型的,所以我不能通过我的测试类测试它(我也不关心)。因此,我的行覆盖率仍然只有 88%。

图 2. 谁说没有第二次机会
 

  正如您看到的,使用一个代码覆盖工具可以 揭露重要的没有相应测试案例的代码。重要的事情是,在阅读报告(特别 是覆盖率高的)时需要小心,它们也许隐含危险的信息。让我们看看两个例子,看看在高覆盖率后面隐藏着什么。

 
 

上一篇:为什么要用UML建模之面向对象建模  下一篇:函数库、组件产品的测试方法