`
jiangduxi
  • 浏览: 453232 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

怎么抽取一个测试模块?

阅读更多
[/b][b]问题:
   当为一个产品类编写了好几个测试,它们含有重复的代码。因为我们知道重复的代码是软件中很多问题的根源,怎么 消除代码中的重复性。

背景:
    为同一个产品类编写几个测试的时候,你最先注意到的模式之一就是每个测试开始的那几行代码总是很相像。每个测试都有三个基本的组成部分:创建一个对象,调用一些方法,检查结果。每个测试的第二部分总是不同的,对不同方法的调用可以区别不同的测试:"如果用这些参数调用构造方法,希望看到这样的结果;但是如果传递了空值,那么构造方法应该抛出那样的异常"。
   测试的第3部分,检查结果,这完全依赖于你所调用的方法,如果测试调用的是不同的方法,当然期望的结果也是不同的。一般情况下,在这部分,只有在反复调用同一个方法的时候才会有重复代码出现。

  然而,创建对象会产生测试之间的重复代码,而且绝大部分重复的代码都出现在这里,在一个类中除了构造方法以外还有很多方法需要测试,所以一旦为这个类编写了第二个测试,就重复了第一个测试中"创建一些对象"的部分,因为很可能用相同的参数调用了相同的构造方法,这样的重复代码实在是很常见,所以如果Junit能有一种内置的机制来消除它,那就再好不过了。

那么如果将要测试的对象称为测试模块:一种对象的"配置",其行为是可以预见的。这样的话,我们可以将测试第一部分----"创建一些对象"称为“创建一个测试模块”。目的是创建一些对象并且将其初始化成某种已知的状态,以便在使用它们调用一些方法的时候,可以预见到结果。

技巧:
   从测试中找出重复的测试模块代码,将这些代码移动到一个叫做setUp()的方法里面。修改后的代码可能不需要编译,因为现在是在setUp()方法中声明变量,然后在测试中使用这些变量。将这些变量放在实例级的参数域中,这样setUp()和测试代码都可以使用它们。因为每个测试是执行在其自己的实例中,所以不必担心在不同测试之间实例级的参数域会被错误地改变。在执行测试的时候,test runner会在每个测试之前调用setUp()方法。测试类中的每个测试都可以使用这个通用的方法初始化。

代码演示:
下面代码Money JavaBean及方法就不给出,可以根据测试代码,自己推出
   public class MoneyTest extends TestCase{
   
      public void testAdd(){
           Money added = new Money(12,50);
           Money augend = new Money(12,50);
           Money sum = added.add(augend);
           assertEquals(2500,sum.inCents());
         }
      public void testNegate(){
          Money money = new Money(12,50);
          Money opposite = money.negate();
          assertEquals(-1250,opposite.inCents());
        }
     
      public void testRound(){
         Money money = new Money(12,50);
         Money rounded = money.roundToNearestDollar();
         assertEquals(1300,rounder.inCents());
        }
    }

注意上面的三个测试的第一行几乎是一样的,似乎可以将这个对象移到setUp()方法里。因为testAdd()方法将这个对象叫做added而其他叫money,首先需要将added相关money以使得三个测试的第一行都一样,然后就可以将这一行移到setUp()方法里去。最后,将money从一个本地变量变成一个实例级的参数域,使得setUp()和所有的测试都可以使用它。接着看看改动后的代码:
   public class MoneyTest extend TestCase{
       private Money money;
 
       protected void setUp()throws Exception{
          money = new Money(12,50);
       }

       public void testAdd(){
         Money sum = added.add(augend);
         assertEquals(2500,sum.inCents());

       }
       
       public void testNegate(){
          Money opposite = money.negate();
          assertEquals(-1250,opposite.inCents());
        }
     
      public void testRound(){
         Money rounded = money.roundToNearestDollar();
         assertEquals(1300,rounder.inCents());
        }

     }

上面这样的做,我们其实在数学中有个概念很好的用来说下:那就是将方程式进行变形然后提取公因式。任何东西都是可以进行检讨和讨论

讨论:
   Junit通过方法setUp()和teatDown()提供了对测试模块的支持,可以在junit.framework.TestCase中找到他们。在创建TestCase的子类的时候,可以重载这些方法来为每个测试建立或者销毁测试模块。要了解Junit是如何使用这些方法的,可以查看另一个TestCase方法runBare()的代码:
  public void runBare()throws Throwable{
       setUp();
   try{
      runTest();
        }
   finally{
         tearDown();
       }
   }

在执行测试的时候,框架会首先调用runBare()方法来设置一个测试模块,运行测试,然后再撤销测试模块。注意将tearDown()放在finally块中,就能保证它一定被执行,即使测试失效,这个方法是为了释放资源,避免资源浪费。
分享到:
评论

相关推荐

    想做金融测试,那银行测试工作内容?职业测试人经验?来吧,看看SIT测试和UAT测试测试的区别?

    1. 测试需求分析:理解测试目标,抽取并评审测试需求。 2. 测试计划制定:确定测试范围,规划时间和方法。 3. 测试用例设计:编写详细测试方案和测试用例。 4. 测试用例执行:执行测试,包括回归测试,并由项目组...

    抽取linux内核链表模块

    这些链表是双向循环链表,每个链表节点包含两个指针,分别指向前一个节点和后一个节点。节点结构通常定义为: ```c struct list_head { struct list_head *next, *prev; }; ``` 为了方便操作,Linux内核提供了...

    一个抽取幸运观众的代码

    在IT行业中,开发一个“抽取幸运观众”的代码是一项常见的任务,尤其在举办各种线上线下活动时。这个程序的主要目的是通过算法确保公平性,随机地从参与者名单中选择出幸运儿。以下是一些关于这个主题的关键知识点:...

    cic.rar_CIC测试_cic_cic verilog_vhdl cic_抽取

    数据抽取是数字信号处理中的一个重要概念,它是指将连续的采样点按照一定的比例减少,以降低数据速率,从而节省存储和处理资源。CIC滤波器在抽取过程中可以提供良好的抗混叠效果,尤其是在高抽取因子下。 CIC滤波器...

    [源代码] C# WinForms 模块 - 学生考试模块

    本资料提供了一个C# WinForms的学生考试模块的源代码实现,旨在帮助开发者了解如何构建一个功能丰富的在线测试系统。下面我们将深入探讨这个模块的关键知识点。 首先,随机抽取试题是考试模块的核心功能之一。在C#...

    odi 知识模块开发

    2. **文档记录:**为每一个知识模块编写详细的文档,包括使用说明、输入输出格式、异常处理策略等。 3. **版本控制:**采用版本控制系统管理知识模块的开发过程,以便追踪变更历史并支持多版本共存。 4. **性能调优...

    高中一年级数学必修3模块测试题.doc

    4. **程序框图与输出值**:程序框图用于表示算法的逻辑,根据描述,这是一个累加过程,输出S的值应该是所有输入项的总和。无法提供具体答案,因为没有给出完整的程序框图和输入数据。 5. **辗转相除法(欧几里得...

    数据测试专用例子.txt

    最直接的方法是从实际业务数据中抽取一个子集作为测试数据。这样可以确保测试环境尽可能地接近真实环境。但需要注意的是,为了保护用户隐私和数据安全,必须对敏感信息进行脱敏处理。 #### 2. 生成模拟数据 当无法...

    公共方法抽取

    在软件开发过程中,"公共方法抽取"是一个重要的代码优化和重用策略,旨在提高代码的可维护性和效率。公共方法是指那些在多个类或模块中重复出现,具有相同功能的函数或方法。通过将这些方法抽取出来,形成独立的组件...

    pythonwebdriver自动化测试实战.doc

    Webdriver 是一个跨平台的工具,允许程序控制浏览器并进行自动化测试。在实战中,我们通常会遇到各种策略和模式来优化测试脚本,提高其效率和可维护性。 线性测试是最基础的自动化测试模型,它模拟用户的一系列操作...

    可选模块的使用与开发

    在IT行业中,模块化开发是一种常见的软件设计策略,它允许我们把复杂的系统分解为一系列可重用、可独立测试和可扩展的组件。"可选模块的使用与开发"这一主题,显然关注的是如何有效地利用和创建这些模块,特别是在...

    旗舰版AD7606模块.rar 旗舰版AD7606模块.rar

    旗舰版AD7606模块可能是一个完整的设计套件,包含了该器件的硬件电路板和相关的软件资源,以方便用户快速评估和集成到自己的系统中。 首先,AD7606是一款16位、单通道、高速ADC,其采样速率可高达1 MSPS(百万样本...

    基于 Pytorch 的深度学习三元组抽取

    深度学习三元组抽取是自然语言处理领域中的一个重要任务,主要目标是从文本中抽取出实体以及它们之间的关系,形成(头实体,关系,尾实体)的三元组形式,为知识图谱的构建和增强提供数据。PyTorch 是一个流行的深度...

    C#实现随机抽取名单效果-支持导入导出

    在本文中,我们将深入探讨如何使用C#编程语言来实现一个功能完备的随机名单抽取系统,该系统具备导入和导出名单的能力。首先,我们需要理解C#的基本语法和面向对象编程概念,因为这是构建此类应用的基础。 1. **C#...

    ODI工具抽取数据操作手册

    ODI(Oracle Data Integrator)工具是Oracle公司提供的一个数据集成解决方案,主要用于数据抽取、转换和加载(ETL)过程。本操作手册将详细介绍如何使用ODI进行数据抽取实验。 首先,准备工作至关重要。你需要安装...

    delphi 抽奖系统 随机抽取 奖励

    本文将深入探讨如何使用Delphi这一强大的面向对象的编程语言来构建一个随机抽取奖励的抽奖系统。 Delphi是Embarcadero Technologies开发的一款集成开发环境(IDE),基于Object Pascal语言,以其高效、简洁的代码和...

    1-1000个数字中随机抽取1组数据

    如果我们要抽取一组数据,比如一个包含10个数字的数组,可以使用循环来实现: ```python # 抽取10个1到1000之间的不重复随机数 random_numbers = set() while len(random_numbers) random_numbers.add(random....

Global site tag (gtag.js) - Google Analytics