正 文

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


www.7dspace.com  更新日期:2006-3-13 6:24:07  七度空间


  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. 谁说没有第二次机会


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

4页,页码:[1] [2] [3] [4] 

上一篇:Linux系统下的网络监听技术
下一篇:Word入门动画教程88:使用公式编辑器
追求代码质量: 不要被覆盖报告所迷惑 作者:Andrew Glover 来源:ibm
收藏此页】【打印】【关闭
站 内 搜 索
 

热 点 导 读
特 别 推 荐