敏捷的软件测试 必须纠正十大误解
 

2009-02-26 作者:袁发明 来源:IT168

 

敏捷方法已经获得了越来越广泛的应用。这是很容易理解的,特别是从开发人员与用户的角度来看。

1. 用户——系统的需求与过程上的细节问题似乎永远也问不完,然后还要仔细阅读大量的说明文档,而他们明白这些文档会成为将来法庭上的证据。

2. 开发人员——需要严格地遵循说明文档而无法表达自己的想法或发挥创造性天赋。他们知道即使有更好的办法,他们也不能更改说明文档,否则这就会成为将来法庭上的证据。

但是对于质量保证人员来说,敏捷方法却会带来麻烦——在原来的理想情况下,他们只需要用既有的说明文档来验证"完成"的产品。要根据一个变化的背景验证一个活动的目标是很不直观的。这表示所使用的技术与自动化也更复杂,并且需要一个新的测试方式,一种类似于用户和开发人员之间的关系的方式。

所有的敏捷方法都有(至少)一个共同的特征,那就是对QA职业的影响。如果所谓的影响是质量上的一次大飞跃,那倒也不是什么坏事。但是,如果决策是根据无效的范例做出的,改变就不一定能与过程同步了。对于开发人员来说,新提出的软件开发范例以开发人员为中心可能是很平常的事。Abraham Maslow曾经说过:"擅长用锤子的人喜欢从钉子的角度考虑问题。"但是作为质量保证人员,我们不能装作敏捷开发不存在的样子,我们必须保证那些拿着锤子的人不会去硬敲一颗螺丝。

某些人可能会对QA提出怀疑,认为测试驱动开发(TDD)才是测试的关键。但是,伴随着需求和方案的发展,QA在整个过程中都是与敏捷小组直接发生联系的,是整个测试设计团队不可或缺的一部分。但这只是QA团队所面临所必须解决的众多误会中比较表面的一个。

对测试的误解

最近看了网络上所谓专家写的文章,发现了一些对TDD与QA部门的误解。本文将解释部分误区,并集中讨论QA团队要在敏捷的世界里获得成功所必须解决的一些问题。

1. "你只需要做单元测试——TDD测试已经足够"

对于大部分商业开发来说,根本就没有这回事。即使是敏捷开发的强力拥护者也承认他们需要一系列的测试技术。

TDD程序设计人员需要这些测试来验证代码的正确性。如果需求(测试用例)解释错误,那么你构建的代码也将无法达到目标要求。

大多敏捷项目都会使用探索性测试方法(黑盒)来支持白盒测试,而不会认为这两种技术只能选一。优秀的探索性测试可以在开发地过于深入之前发现开发人员所忽略的问题。

2. "你可以重用单元测试来创建回归测试集"

有些TDD拥护者认为常规的下游测试(downstream testing)是多余的,因为每一行应用代码都有对应的测试用例;他们认为重用单元测试就可以做到用户验收测试和回归测试所能做到的一切。

这听起来挺有道理,但由于某些原因,这是不现实的:TDD中的白盒单元测试的粒度与目标与下游黑盒测试的目的是不同的。

虽然单元测试的整体目标是保证代码能够实现所需的功能,但是回归测试的目标是保证被改动的应用代码不会产生意料外的效果。这两个目标是不同的--比如,检查一项属性是否具有合法的日期格式,与检查输入域中是否存在所需的日期是不同的。

3. "开发人员可以用开源工具写测试,因此我们不需要测试人员或者自动测试工具了"

职业测试人员实现的是与其开发同僚不同但同样有效的作用。

人们普遍认识到传统的自动测试工具并不像供应商们炒作的那么有效。原始软件的源码和供应商的产品一样可以改善数据库测试环境下的效率。这是因为没有合适的工具可以提供用户界面测试,所以我们才把方案扩展到了这一领域;我们的传统是有效地实施测试而不是屏幕抓取自动测试。我们开发了测试驱动,是因为在过去的二十年里传统的供应商错过了这个机会。

通常,TDD项目的测试代码至少与应用代码一样多,因此其本身就是应用软件。这种测试代码是需要在目标应用的生命周期中进行维护的。

4. "有了单元测试就不需要手动测试了"

手动测试是一项重复性很强的工作;成本昂贵、枯燥并且容易出错。虽然TDD可以减少功能测试所需的手动劳动,但是它不能消除对黑盒测试(手动和自动)的需求。

通过自动抓取测试人员的过程并记录其键盘和鼠标动作,测试人员能够腾出更多的时间来进行更有意义、更有价值的活动,比如测试难以(甚至无法)自动化的复杂场景。虽然手动测试很费时间(因此也很昂贵),但是如果因为不进行手动测试而漏掉一些错误,则通常意味着将来可能要付出更大的代价。

5. "我们不再需要用户验收测试"

在敏捷开发中,用户验收测试的定位通常是和用户协作确定"错误的需求",而不是检查功能是否与需求匹配。用户在最开始定义需求的时候,他们是根据自己的期望值来描述的。当他们看到"活生生"的系统的时候,他们必然还会产生一些不同的、或者额外的需求。虽然敏捷方法可以减少这种事情的发生概率,但是要完全解决这种问题还是不可能的,因此我们无法回避用户验收测试。商业用户的用户界面验证就更无法回避了,因为他们想象的可能与开发人员稍有不同。而这就得由我们来……

6. "自动化是不可能的"

在敏捷项目早期实现自动化通常很困难,但是随着系统的发展和成长,某些方面已经确定,这时就该进行自动化部署了--通过自我修复脚本等处理改动。

开始的时候,用户与QA的所有测试几乎都是手动的,但是如果能够抓取并重用这些测试活动和设计,这对以后的工作了是有益的。

自动化的时机很难掌握,因此一定要使用能够先支持手动测试而后可以将其发展为自动测试的工具。

7. "开发人员都有足够的测试技能"

前提是测试简单到所有人都可以做,并且每次提交的代码都是完美的。可惜,许多企业都只在开发人员的编码技术和为他们提供最新的集成开发工具上投资,而忽视了发展他们QA团队的测试技能,或者没有为他们提供与开发人员同样有效的工具。

一个独立的测试团队就像一个客观的第三方,可以清楚地看清"全局",能够验证可交付产品的功能与质量。虽然开发人员会尽力提供所需的系统功能,但是一个优秀的测试人员还是要客观地提出"万一……"之类的问题。如果你还考虑到了商业用户测试,那你就更有可能完成一个符合要求的系统。

最后,虽然下面的观点可能引起争议,我还是要说大多开发人员实际上并不想花大量的时间先写测试再写代码来验证测试。如果以下描述的协作过程,开发人员可以获得足够的功能测试方面的帮助,从而集中精力编写精准、稳定的代码。

8. "单元测试就是设计说明书的全部"

不管用什么开发方法,在编写代码之前都要想清楚需求。虽然TDD说"做得不错"可以代表设计说明中的很大一部分已经完成,我们仍然需要考虑单元测试中的一些空白。还有其它同样可行的方案。TDD要验证需求采集的准确性,而他们的依据并没有得到历史的证明。

用定义测试用例的方法来验证需求的准确性与简洁性已不是什么新概念。比如V模型,就是一种了解测试需求的有效方法--通常指功能性需求。就像TDD一样,如果业者比较严格,而开发过程比较灵活,那么V模型以及其它模型就没有办法了。软件工程并不像机械工程,强制顺应只会浪费精力。不管你选择了哪种方法,都要问每个用户需求:"我怎么来测试这个?"关键是要在代码构建前检查测试用例,否则你会花费更多的时间进行代码重构.

通过协作对需求进行精简以后,开发人员就可以拿到一份比较稳定的说明文档,这份文档可能会较少地发生变动,因为它已经经过了多方面的评定。

9. "TDD适应于任何项目"

随着项目规模的增大,进行测试的时间也越来越长。这个问题可以用对项目和/或测试进行划块的方法解决。无论哪种方法都会产生要根据其与当前代码的相关度运行的测试。这导致了对测试计划和执行管理需求。为了获得较高的效率,除了白盒测试,你还需要考虑:

集成测试——"我需要哪些测试来保证新代码与其它代码能够无缝合作?"

系统测试——"新代码支持的功能与系统或其它系统的功能结合密切吗?"

回归测试——"为了保证新代码不会产生不可预料的反作用,我需要以多大的频率运行回归测试?"自动回归测试可以有效地验证敏捷开发技术。

用户验收测试——"虽然TDD(与业务用户协作)可以保证某个特定的功能能够正常工作,但是经过各种各样的变动之后,累积的影响还能被用户接受吗?"

然而,在今天的环境下是无法将这些测试阶段当作一系列独立的活动的。通常,每次我们加入新代码的时候,就需要同步进行这些测试。随着项目团队(及测试)规模的扩大,测试也变得无法"自我描述(self-documenting)"。项目的参与人越多,项目就越容易受到各种对说明文档的不同解释的影响--对这些定义的误解正是导致失败的原因。

随着项目规模的增大,需要编写的测试代码也就越多。任何测试代码都需要在应用的整个生命周期中得到支持--这极大地增加了维护的难度。

随着测试负担的提高,项目需要增加自动测试来最小化人力干预并减少进行这些测试所需的时间。

10. "开发人员与测试人员,是油与水的关系"

开发人员与测试人员自诞生之初就是"他们与我们"的关系。这通常是一种健康的共生关系。如果处理得当,两个团队之间互助的关系可以为客户提供更高质量的产品。

应该重点讨论的是:

  • 满足业务目标的软件交付(满足要求、及时、并且控制在预算内),而不是谁控制过程中的哪一部分。
  • 需求采集阶段测试人员怎样参与到TDD过程中?
  • 测试人员如何最大程度地重用开发阶段中创建的资产?
  • TDD中有没有"传统的测试人员"?他们(就像开发人员)是否应该学习新技能以适应新的范例?
  • 测试人员与开发人员在利用先进的软件开发和测试工具的时候如何发挥互助的作用?

正如开发人员的软件工具和方法使开发方式发生了转变一样,下一代自动测试工具也为测试人员带来了新的机遇,使他们可以在交付周期中更早地进行自动测试而不会遇到传统的自动测试工具所带来的繁重的脚本维护负担。

总结

敏捷项目实际上是让QA部门引领敏捷过程的好机会——没有人比他们能更好地将用户与开发人员联系到一起、了解两者的要求、满足他们的要求并保证在部署之前完成所有工作。QA除了要继续保证整个系统的进展能够满足业务目标并符合要求,他们还应该在决定结果及怎么做上有优先权利。这需要QA人员能够灵活应变,抛弃原有的范例并集中精力研究技术以获得最优的测试方法。


火龙果软件/UML软件工程组织致力于提高您的软件工程实践能力,我们不断地吸取业界的宝贵经验,向您提供经过数百家企业验证的有效的工程技术实践经验,同时关注最新的理论进展,帮助您“领跑您所在行业的软件世界”。
资源网站: UML软件工程组织