软件测试的革命

发表于:2007-4-09 11:28

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Sam Guckenheimer    来源:本站原创

爱因斯坦在1915年发表了广义相对论,当时这还只是一项伟大的科学猜想。4年后,Arthur Eddington和一个英国科学家组成的小组完成了一项重要的实验,在实验中他们拍摄了在日蚀过程中Hyades星云的图片,该实验表明,因受日蚀影响,图片中产生了很大的误差幅度,由此证明了爱因斯坦关于空间的弯曲和光的重力效应的预测。大众媒体随即给予爱因斯坦和Eddington很高的荣誉。同时也因为他们两人都是和平主义者,所以被一起推崇为在这个饱受战争沧桑的世界上的英雄。
    虽然媒体显得急不可待,但值得注意的是,广义相对论在当时的科学界仍受到广泛的争议。直到半个世纪以后,人们才终于迎来了具有决定性的实验结果。当时Thomas Kuhn写下了《科学革命的结构(The Structure of Scientific Revolutions)》一书,相对论被作为是革命性变革的完美例子--一种新的观念完全替代了一整套旧的信仰。

    今年7月,我代表Rational Edge采访了Cem Kaner。当时他借用了Kuhn的结构对目前软件测试领域盛行的各种争议和尚未确证的理论进行了分类。

    后来,Rational Edge发表了我和软件测试方面的其他专家的一些访谈。有些读者却质疑我的选择,他们会问:这和我现在做的主要工作有什么关系?
    因此,在本文中,我想把所有这些课题放在一起,并对自己关于未来测试领域的发展的前瞻进行阐述。我可以断言的是,测试人员、开发人员、项目管理人员、公司管理人员和最终用户们都期待着看到在这10年里软件测试实践方面将要发生的大变革。其原因很简单,--软件质量的低下已经使美国经济蒙受巨大损失,NIST估计[1],每年损失约600亿美元,而Standish组织的数据则是2000亿美元。所以改进软件质量已成为取得高投资回报率(ROI)的直接途径,只有那些把握了软件质量的企业才会赢得胜利,其余的则将被人们所遗忘。

    这些实践和工具又是什么呢?我认为随着时间的发展,以下五种趋势会得到发展和应用。

    1.测试驱动型的软件开发。在软件生命周期的各个阶段中,这些阶段包括测试、需求分析、使用形象化符号进行的规格说明,以及基于UML和其它新标准的实践;

    2.探索性学习和发现,这将成为迭代开发过程的一个组成部分;

    3.组件测试和易测试性设计,这将成为软件开发不可分割的组成部分;

    4.更加重视适当的技能的应用,减少预先写好的文档,这将成为优秀软件过程的基本原则之一;

    5.使用自动化测试来取代目前严重影响测试效率的冗余繁复的人工过程。

    下面让我来对这些趋势进行说明。

 

    测试驱动型开发

    这一实践在RUP过程中又称为测试第一的设计(test-first design,而在很多XP( eXtreme Programming)文章中则称之为测试第一的开发(test-first programming。这一设想的提出至今已有近十年了,但是直到最近才得以在开发这一层次上取得很大的支持,这要在很大程度上感谢敏捷方法组织。他们的核心思想是,在你写一行代码之前,你要先写一行对其失效所进行的测试。在该测试的描述中应包含一个程序代码实际运行的实例。Martin Fowler将这样的测试称为带实例的规格说明(specification by example
    Brain Marick和其他一些敏捷测试的支持者已经提出建议,要把测试驱动开发的概念扩展到所有的层次,包括系统测试和产品级测试[2]Marick很清晰地表述了他的观点:我并不想写出一套用于捕捉用户愿望的需求,取而代之的是,我要写出一套测试,一旦这些测试能够通过,产品就能使她满意。所以我放弃需求编写的步骤,而直接把需求分析加入到测试的创建过程中去。”[3]这些测试脚本就象是可执行的规格说明,当程序代码通过了测试,那么这些程序代码也将和规格说明保持一致。

    如果你的代码是使用Java,而且你的测试也在Java中测试,那么测试很可能会基于JUnit,你可能要么是一个人,要么是编写的两人组中的一个,不管是哪一种情况,都很容易看到,这时Marick的方法是可行的。Marick相信这是可伸缩的,可以适合于小团体,或者在有一个用户在场的条件下进行交谈式测试的创建(conversational test creation的实践。但是,如果有人要了解需求,这些需求却是在测试设计中被捕捉的,而你并不在场,无法直接为他们进行解释,这样就存在明显的问题。在这种前提下,我并不认为测试一定要在程序语言中体现。即使对需求有了精确的表达,也不足以解决可理解性的问题。对于这一问题,LeffingwellWidrig有很好的描述[4],下图即是基于他们的观点。

                                               

1:可理解性问题(基于LeffingwellWidrig的观点)


    实际上,LeffingwellWidrig并没有真正地考虑到测试的问题。他们的主要目的是想让需求具备很高的可理解性,以便于让用户和投资者能够充分理解。他们没有解决这样的问题,即如何把规格说明提交给其他投资者和生命周期的其它阶段。作为一种争议,他们认为有必要保留一部分不明确性。而实际上,不明确的需求显然会让测试人员发疯。
    Marick提出的测试驱动型开发方法则走向另一个极端:测试代表了需求,测试的表现形式是一些可编译、可执行的代码。但是,如果测试(需求)的唯一表现形式是代码的话,你就很难和商务人员/投资者/客户进行有效沟通,甚至也很难和其他测试人员及开发人员进行沟通。所有这些人都认为测试的形式本该是数据和流程,所以如果要以那种方式来做的话,你的测试必须变得非常容易进行交流。

    一些公司正致力于为这种隔阂提供解决之道。Rational正积极参与一个OMG团体关于UML测试预定义项目,该项目可以把测试表示为数据和可视化的流程,例如顺序图和活动图。我们正在开发一些工具来对待以下三种表示方法,代码,数据和流程,并取代类似的测试视图。

    在过去,我们制作了这些实例化规格说明,按照RUP的命名方法,可称之为用例实现实例化规格说明用例实现的相似性可以通过援引最近的一个使用Agile方法的工作团体的报告来说明:

    [一个参与者]提到,和他一起工作的人都很喜欢使用测试第一的开发方式。当测试框架被开发好以后,特别是当用于组织运行的测试脚本被定义好时,他们的工作变得更为容易。而用例在组织起来开发脚本时会有所帮助。他们的测试可以捕捉到用户的需要。人们之所以喜欢这样的方法,其原因是它提供了他们工作所需的结构。在Agile方法中,需求以案例(story)”的形式存在。于是,测试脚本将以接口已明确定义好的形式把这些案例编织在一起。这意味着结对编程的人可以根据他们需要的顺序相互测试接口[5]

    类似地,OMG测试预定义工作组发现,将UML排列起来也很容易。你可以将一个用例实现转成为测试,这只需增加两件东西:验证工作(例如,现在用测试来检查这个软件中的条件。)以及裁决(例如,通过、失败,或者暂不决定)。这样的信息在规格说明中随处可以捕捉到,所以UML符号可以让我们测试人员有了表达的手段。

    于是,只需要额外做一点点努力,就可以使测试对客户来说变得很容易理解:数据表和可视化流程。然后,当有软件需要测试的时候,测试已准备就绪。这一实践使测试驱动型开发在系统级测试上也具有实用的价值,因为在设计工件和测试设计工件之间确实没有什么区别。仅仅只要增加验证的注解以及进行裁决就可以了。在比较容易理解的可视化流程和数据的帮助下,你不再需要把系统设计从测试设计中分离出来。而且由于这些流程具有一个可执行的形式(生成的代码),因此可以把每一次创建作为测试来执行。这使整个团队得到了解放,并成为Kent BeckErich Gamma所说的"受影响的测试(test infected": “...这是一种测试的类型,只要使用非常小的投入即可使你成为一个更快的、更多产的、更具预见性的、压力更小的开发者。

-Kent Beck
Erich GammaTest Infected: Programmers Love Writing Tests[6]

31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号