做好单元测试需要保证的三个独立

发表于:2012-02-06来源:未知作者:dellfox点击数: 标签:
做好单元测试需要保证的三个独立单元测试是针对代码单元的独立测试。“独立”是指将代码从原始项目及其依赖的环境中隔离出来,针对各个单元单独进行测试,包括三方面含义:形式独立、实质独立和意识独立。单元测试之所以困难,就在于技术上无法解决形式独立和

  单元测试是针对代码单元的独立测试。“独立”是指将代码从原始项目及其依赖的环境中隔离出来,针对各个单元单独进行测试,包括三方面含义:形式独立、实质独立和意识独立。单元测试之所以困难,就在于技术上无法解决形式独立和实质独立,主观上没有达到意识独立。

  形式独立

  将测试任务从原始项目及其依赖环境中隔离出来,并能在易于测试的环境下运行。企业项目通常高耦合、可测性差、依赖于特定的软件环境或硬件环境,单元测试要首先将测试任务从依赖的代码和环境中分离出来,并解决编译、平台差异等问题,使测试任务在易于测试的环境下能够独立测试。

  实质独立

  被测试代码通常会调用各种底层函数,其功能逻辑难免受底层函数的影响,如何独立完整地进行测试?实际上,调用底层函数获得的数据,与通过参数传递的数据具有同等意义,例如,调用底层函数得到一个返回值,要测试的是被测程序对这个值的各种可能有没有做合适的判断处理,并不关心底层函数如何计算这个值,正如只关心是否对参数的各种可能做了合适处理,而不关心参数是如何传递和由谁传递一样。因此,调用底层函数获得的数据可视为被测函数的一种输入,称为内部输入。

  如果可以模拟底层函数的各种输出,并将这些输出视为被测函数的内部输入,那么,无论底层函数属于哪种情形,都可以完整测试被测代码的功能逻辑,这就是实质独立。

  内部输入分为易于自然取得(调用真实的底层函数获得)、不可控(调用真实底层函数但其行为难于控制)、失真(打桩的必然后果)、难于自然取得等四种情形。易以自然取得的内部输入并不影响被测函数的独立性,而后三种则是单元测试的关键难点。静态局部变量也是麻烦的内部输入。关于内部输入的详细说明,请看这篇文章。

  意识独立

  意识独立是主观要素,是指在制定测试目标和执行测试时,要适应“单元测试是针对代码单元的独立测试”这一基本现实,把测试任务看作一个一个的独立单元,正确设定测试目标、正确选择测试方法及工具。

  单元测试有独特的优势,例如易于完整地测试代码单元的功能逻辑,这些优势来自“独立”,但凡事有其长必有其短,既然是“独立”,就难于测试与其他代码和依赖环境的相互关系。单元测试与系统测试是互补关系,不是代替关系,“独立”状态下易于发现的错误,才是单元测试的目标;集成后才易于发现的问题,应该留待系统测试

  代码单元本身的功能逻辑错误都是单元测试的目标,而性能问题(时间性能如执行速度,空间性能如存储空间大小、内存泄漏)难于在最小单元内测试,不是单元测试目标。

  单元测试也不考虑平行和向上依赖关系,并把向下依赖抽象为内部输入,例如,测试一个函数时,不考虑这个函数在项目中是被普通调用、系统回调、消息或信号调用、还是中断调用;不考虑多线程、重载;嵌入式环境中的端口、寄存器等在代码中都是内存,视为全局变量;并把底层函数(包括操作系统API)的输出视为内部输入。总之,只用各种输入是否产生了正确输出的方式,完整测试函数的功能逻辑,也正因为这个原因,单元测试可以脱离原来的平台环境,在易于实施的平台上进行,例如,在PC上测试嵌入式项目,在Windows上测试Linux项目,都是可行的。

  编码规范检查与单元测试无关,无论是否实施单元测试,编码规范检查都是必不可少的工作。静态分析属于全局扫描,严格来说也不是单元测试,提高编译器的警告级别,就是最简单高效的静态分析。

  单元测试是意义重大且困难的工作,目标应该具体而明确,将不属于单元测试或单元测试不擅长的目标牵扯进来,其结果往往是“拣了芝麻,丢了西瓜”。

原文转自:http://www.ltesting.net