All About Smart Testing

探索式的自动化测试开发

上一篇 / 下一篇  2010-04-05 19:14:53

 
February 22

探索式的自动化测试开发


我的工作要求我编写自动化测试用例来测试系统。所谓自动化是指,测试的建立(set up)、执行(execution)、检查(verification)和拆卸(tear down)是无人值守的。这些测试用例被加入到每日测试(daily test)中,以测试每日构建(daily build)所生成的当日构建。这篇短文旨在总结我的测试实践,介绍如何用一种探索式的方法来开发测试用例,权当抛砖引玉。

在介绍具体的方法之前,需要明确自动化测试用例开发的目标。

  1. 迅速找出重要的程序问题[Cem01]。尽快的发现项目的重大风险,有助于开发团队以较低的代价修正严重的错误。这要求,首先测试核心功能、常见场景、高风险区域,然后测试辅助功能、罕见场景、低风险区域。为了探测高风险的区域,需要对各个模块进行广泛的测试,以发现问题较多的模块;为了发现严重的问题,需要对一个模块进行深入探索,以发现隐蔽的错误。有时候,测试的广度和深度不可兼得,需要根据项目情况进行平衡。
  2. 测试应该有助于提高质量[Gerard07]。测试用例可以看作“可执行的规范”,定义了各种场景中被测试系统的行为。这份规范应该是易读的,很容易理解测试了什么内容;它应该是尽可能完备的,规定了被测试系统大部分的行为。在回归测试中,这样一份规范可以防止引入缺陷,并尽快定位异常行为的原因。
  3. 测试应该易于编写和维护[Gerard07]。软件测试是一个探索的过程,需要不停的增加、修改、删除测试用例,以反映对被测试系统不断深入的认识。当被测试系统发生变化时,自动化测试用例也需要随之修改。如果测试用例很难修改、很容易失败,那么测试者的时间往往耗费在测试维护上,而不是错误侦测上,这是得不偿失的。

测试用例开发不是线性的过程,需要不停的尝试,需要根据新的情况制定新的方向和策略。虽然本文用列表的方式介绍我的方法,但是在真实的测试过程中,它们是交错且迭代的。

  1. 选择或开发一个适合的测试框架。测试框架提供了测试领域的可复用解决方案,使得测试人员可以专注于业务领域。xUnit家族、开源框架和商业产品都是很好的选择。如果没有适合当前项目的框架,也可以自己开发一个。例如,我使用IronPython作为测试开发语言。我没有使用Python标准库,因为它依赖于一些CPython的module(需要部署CPython),而我只想要一个纯.NET的解决方案(只需要部署.NET framework)。我也没有使用NUnit或MSTest,因为它们要求编译出测试程序集,而我则希望没有“编译”过程。于是,我开发了IpyUnit,用于自己的测试,效果颇佳:既利用了.NET framework的强大能力,也发挥了Python语言灵活快速的优点。这里的诀窍是,只开发当前需要的功能,不追求其他框架提供的高级功能。
  2. 收集并理解规格说明。大多数项目没有规格说明,即便有也已经过期。测试者需要收集任何显式和隐式的规格说明[Cem01],例如需求文档、会议纪要、相关产品、同一产品的老版本、邮件、wiki、聊天中的只言片语、实现代码等。在处理这些信息的过程中,会产生许多疑惑。这时,可以与同事交流,厘清头绪;也可以开发测试,让代码来提供答案。理解规格说明的目的是了解业务需求和技术实现,从而找出重要的功能和高风险的区域,为进一步的测试指明方向和策略。
  3. 开发基本测试用例。基本测试用例用于检查系统的主要功能和常见场景。它们应该包括正面用例和负面用例,同时从快乐路径(happy path)和异常路径(exception path)来检查被测试软件。基本用例是最基本的“可执行规范”,定义了软件的基本行为。回归测试应该总是包括基本用例,以提供基本的安全网。
  4. 阅读被测试软件的源代码。阅读源代码的主要目的有二。第一、找出高风险的模块。在大多数项目中,测试者的时间总是非常紧张的。通过阅读源代码,可以快速识别出低风险的模块,降低它们的测试优先级;同时发现高风险的、复杂的模块,针对它们的特点构思测试策略。这有助于制定出事倍功半的测试计划。第二、找出潜在的程序缺陷。静态分析是一种高效的错误检查手段,其中污染传播(taint propagation)分析尤其有效[Brian07]。所谓污染传播是指,程序的输入数据未经过检验(或未经过完备的检验),一直传播到持久性存储(如文件、数据库)或重要的操作(如将数据发送给用户)。测试者的任务就是构造输入数据,使得污染传播造成危害。阅读源代码是构造此类测试用例的捷径。
  5. 困惑是一种测试工具[Cem01]。软件开发从来都不缺乏困惑:阅读规格说明,会觉得莫名其妙;阅读源代码,会觉得匪夷所思;阅读测试结果,会觉得不可思议;阅读错误报告,会觉得不知所云。困惑是指南针,它指出了在规格说明、用户文档、实现、测试中的缺陷。我承认我有时候会忽略我的困惑,转移到其他工作项上。但是,我还是在不断地提醒自己:不要放过任何一个困惑。对于代码和测试上的困惑,我的作法是用一个测试用例来复现令我疑惑的现象,然后用调试器和源代码来调查。这样做可以使“可执行规范”覆盖更多行为,避免测试遗漏。
  6. 增加测试用例来记录对软件的理解。软件测试是一个学习的过程,随着测试的展开,对被测试软件的理解也会更加深入和全面。学习的来源很多,如客户的反馈、手工测试发现的错误、阅读代码发现的问题、团队成员提出的建议等。应该综合这些素材,增加更多的测试用例来增强“可执行规范”。基本测试用例是一个很好的起点,随后测试应该在广度和深度上继续发展。
  7. 利用测试覆盖率来增强测试用例集。运行代码覆盖率分析工具,查看测试没有覆盖哪些语句块,然后补充测试用例,以求100%的语句块覆盖。有时候,我只是阅读代码,搜索显式抛出异常的语句,然后构造测试用例,以触发这些异常。这是因为,快乐路径是很容易被覆盖的(如果没有被覆盖,那么基本测试用例集需要增强),没有被覆盖的往往是异常路径。抛出异常的语句是异常路径的标识,覆盖它可以增加测试覆盖率,还可以检查异常的构造和传播是否正确。对于覆盖率,我还有三点补充。
    1. 100%语句块覆盖需要被测试代码有较好的可测试性(testability)和可观的自动化测试投入。在许多情况下,是难以实现的。但这不应该是紧耦合、强依赖代码(可测试性的死敌)得以存在的理由。[Michael04]解释了为什么可测试性是如此的重要,以及如何通过艰苦的工作去获得美妙的软件。
    2. 分支覆盖是比语句块覆盖更好的覆盖率方法,它可以揭示出更多的可执行路径。但是,我从来没有利用分支覆盖来指导测试用例构造,因此不能提供任何意见。
    3. 测试覆盖率只能避免最差情况,而不能说明测试的质量已经足够。在分析测试覆盖率的时候,测试者要带上“攻击者的帽子”,不停地考虑:代码有没有漏掉一些逻辑?——测试覆盖率显然不能发现那些不存在、却应该存在的代码。
  8. 重构测试代码。随着测试用例越来越多,测试方法(test method)、测试夹具(test fixture)、断言(assertion)、测试辅助(test utility)也越来越多。如果不进行有效的管理,自动化测试会包含冗余的代码和脆弱的结构。这使得测试用例的修改、增加和运行的变得困难,也使得产品代码的小修改导致测试代码的大修改。因此需要对测试代码进行持续的重构。[Gerard07]提供了一批重构手法和模式,是很好的起点。

测试用例的设计是一个迭代的过程,需要在测试过程中不断地收集信息并调整策略。在许多情况下,本文介绍的测试用例开发方法和手工执行的探索式测试(Exploratory Testing)很像(探索式测试并不一定是手工测试)。其关键是用自动化测试用例来记录探索过程中的重要发现。

Reference

[Cem01] Cem Kaner, James Bach , Bret Pettichord, Lessons Learned in Software Testing, Wiley, 2001.
[Brian07] Brian Chess, Jacob West, Secure Programming with Static Analysis, Addison-Wesley, 2007.
[Gerard07] Gerard Meszaros, xUnit Test Patterns: Refactoring Test Code, Addison-Wesley, 2007.
[Michael07] Michael Feathers, Working Effectively with Legacy Code, Addison-Wesley, 2007


TAG:

Smart Testing 引用 删除 liangshi   /   2010-07-25 14:55:17
原帖由kakamissyou于2010-07-22 22:21:08发表
这篇文章是你自己写的?还是翻译的?


这篇文章是我原创的。
kakamissyou的测试小栈 引用 删除 kakamissyou   /   2010-07-22 22:21:08
这篇文章是你自己写的?还是翻译的?
Smart Testing 引用 删除 liangshi   /   2010-04-10 14:55:55
在这篇文章中,我测试的是Web Service。该Web Service提供了一组基于SOAP的Web API,通过调用这些API可以读取或修改后台数据库中的数据。我的测试自动化是实现了一个客户端程序,该程序调用这些Web API。

底层系统的测试自动化确实很困难。一个重要的原因是开发者往往直接调用系统API,使得测试程序难以控制、获取被测试系统的行为。对于此类问题,需要和开发者协作,让尽量多的信息可以暴露给测试程序。
dream517的个人空间 引用 删除 dream517   /   2010-04-10 09:40:02
您测试的内容是什么?
对于底层测试来说,测试自动化真不好做
Smart Testing 引用 删除 liangshi   /   2010-04-07 13:10:56
多谢鼓励!

原帖由fishy于2010-04-07 11:55:37发表
您好,我是51Testing软件测试网的编辑,您的本篇博文被推荐至51Testing软件测试网首页发表:http://www..
FISHY'S TRIBE 引用 删除 fishy   /   2010-04-07 11:55:37
您好,我是51Testing软件测试网的编辑,您的本篇博文被推荐至51Testing软件测试网首页发表:http://www.51testing.com/html/25/n-212025.html
感谢您关注并支持51Testing博客,期待您更多的优秀原创博文。
 

评分:0

我来说两句

Open Toolbar