Archive
自动化测试之惑
自动化测试,就像是一块大馅饼,每个人都想上来啃一口,但是进嘴了,却发现味道各不同,然后心里就会有了各式各样的迷惑。
1、自动化测试脚本谁来写?
这在过去似乎不是问题,在现在一些公司内也许也不是问题:理应由测试工程师来负责实现代码测试并维护,因为他们更理解产品,更需要从客户端角度来测试,更熟悉测试案例。但问题是种种现实决定了让测试工程师对自动化测试起来显得困难重重。
- 项目产品复杂度增高,分工很细。老板一般都会倾向于开发工程师尽快地实现代码,然后测试人员扑上去一顿测,鲜有老板愿意投入独立的资源来让测试人员从事自动化测试开发。而且自动化测试在前期的投入比较大,即使这样,也不意味着自动化测试代码易于维护,成为有效资产保留并延用。
- 快速迭代导致的自动化测试维护难度增大。需求的经常性变更导致代码结构甚至架构上的变化,具体到自动化测试所以来的,就是用户界面和功能经常性的发生变化,如果测试人员和开发者信息不对等(而这一般是常态),测试人员只能拿着自动化测试资产疲于应付,如果本身再不是专职于此,难度可想而知。需要注意的是,即使可以通过一些技术手段来减轻这种快速变化导致的自动化测试难维护性,比如动态识别,但涉及复杂的产品和功能,这样的努力仍然是杯水车薪。
- 测试工程师的代码能力。这是国内一般的通病,测试工程师的技术能力一般是要比开发者低一个档次甚至更多,这种技术能力的不对等,导致测试工程师难以把握自动化测试的开发和维护,因为那也是软件开发,别无二样。而且在“文人相轻”的技术氛围里面,技能的不对等,也很容易造成信息的不对等。测试人员可以说自己是从用户的角度来使用软件和测试,开发者只需要实现代码并修改缺陷。但现在的软件发展根本不再允许有这样清晰割裂开来的团队合作。
- 测试案例很多,但覆盖有限,而测试工程师囿于精力无法作探索性测试。这同样同样是资源受限的问题。
需要什么样的人来编写自动化测试呢?所有人都会同意应该由那些真正对产品的理解,对测试案例的理解很精通的的人来负责。结合上述的问题,和现在的状况,开发者在这方面占有足够的优势。
- 开发者自己的代码模块自己实现,自己也最清楚。需要怎么来测试,有哪些前置条件,会有怎样的输出,从API层到用户界面,自己也可以为自己的自动化测试提供方便,反过来又潜在影响了代码的结构,更加可测。
- TDD的需要。这是敏捷中很好的实践,也是很难做到的实践。但好处大家都知道。
- CI(持续集成)来保证。有持续集成,可以保证测试执行的频率,替代掉手工的无聊并可能导致的错误。
- 测试人员来做其他测试,比如探索性测试,不易实现自动化测试的部分。
2、自动化测试到底难在哪?
有一些问题,在自动化测试实现中,是要考虑的:
- 实现。难度在于有没有一个很好的测试框架来帮助实现,脚本的复杂度有多高,是不是易于编写并重构,是否方便技能传递。在自动化的测试案例越来越多时,结构能否依然保持足够的清晰性。开发人员的技术能力是否达到了所需的标准。
- 变化。变化的风险有没有实现被考虑进去,在代码层和逻辑层能缓冲掉这样的变化对已有的代码实现甚至整个代码结构的冲击。
- 持续投入。自动化测试是需要成本的,尤其在前期,而且也不意味着前期投入够多后来就一定能收获。要投入资源,包括人力、时间、薪水。
3、选择什么测试工具?
这需要依据你要自动化的测试包括哪些,多大的量,多深的技术难度,再行选择。问题是,很多时候,一开始根本对这些一无所知,操起个家伙就开始干,但好歹这样也有吃一堑长一智的机会。我认为在选择工具时,考量的因素包括:
- 要自动化测试案例量有多少?基于Web的还是桌面应用的,还是纯终端的。当然之前要对目前市面上的工具有一个笼统的了解。
- 工具的学习曲线是怎样的?可以很快上手吗?可以很快做技能传递吗?
- 工具的社区效应如何?有足够的参考文档吗?有方便的渠道让你有求必应吗?有源码可以一探究竟吗?
- 公司对选择工具有没有倾向性或者策略上的考虑,如果有,那还选择竞争对手的,或者第三方的就是不甚合适的。
- 工具的发展前途如何?会在你的测试自动化完的时候,甚至还没做完就消亡了吗?
- 工具能允许你的测试案例发生应需的变化而帮助你重构调整吗?能在测试案例日益增多时仍然游刃有余吗?
- 最后一点,我觉得也很重要,这样的工具会让你觉得以后只是在做重复的劳动,还是会让你不停地学到些新东西呢?
4、自动化测试到底可以测什么?
自动化测试什么都能测吗?什么都能覆盖吗?显然不。
- 基于API的自动化测试可以容易实现的,也容易运行并相对容易维护的,比如有些高级的IDE重构功能可以某种程度上帮助你达到这一点。
- 基于UI的很难测,也更难完全覆盖测试。没有一种工具可以帮助你,全部实现你要测试的功能的各个方面,而利用不同工具来实现一个完整的测试案例的自动化,则显得洋枪夹土炮,维护也是个问题。
- 基于Web的则难上加难。因为不同的浏览器对UI的控制是不一样的,你需要考虑自动化测试代码能兼容到不同浏览器。当然,如果你只需要面对一款浏览器,那困难要少一些。
所以,要选择合适的工具,然后要明白能自动化掉的功能是什么,不能的有哪些,不能一味的借助工具,要考虑到工具实现以及运行维护的成本,有的时候手工可以做一下的动作必须要费很大功夫用工具来完成,以追求片面好成本极高的自动化。
这是一个学习的过程,有些经验不做过是很难得到的。
- 5、老板喜欢自动化测试,你喜欢么?
- 自动化测试实现一阶段后,拿出一组数字出来,自动化测试覆盖率多少,节省人力多少,老板看着高兴,自己也开心。但是,是真的开心么?真的对实现了的自动化测试有信心吗?真的能覆盖相应的测试案例吗?可以很好的维护吗?不同的人,心里会有不同大小的结吧?有人会有无知的开心,有人也会有心虚吧。
开源自动测试框架Tellurium
Tellurium自动测试框架是一款针对web应用、基于UI模块的自动测试平台。UI模块是由一组复合的UI对象以嵌套的形式组成,比如,Google的搜索UI模块可以表示成:
ui.Container(uid: “GoogleSearchModule”, clocator: [tag: "td"], group: “true”){
InputBox(uid: “Input”, clocator: [title: "Google Search"])
SubmitButton(uid: “Search”, clocator: [name: "btnG", value: "Google Search"])
SubmitButton(uid: “ImFeelingLucky”, clocator: [value: "I'm Feeling Lucky"])
}
Tellurium框架还定义了一套全新的领域特定语言来进行web测试,比如对于Google搜索模块,你可以使用下面的DSL来完成一次搜索测试:
type “GoogleSearchModule.Input”, “Tellurium test”
click “GoogleSearchModule.Search”
waitForPageToLoad 30000
目前Tellurium已经发布0.6.0版本,InfoQ中文站就Tellurium的方方面面,特地邮件采访了Tellurium的创始人方剑先生:
1、请介绍一下您自己,以及所从事的工作?
我的名字是方剑,曾经在上海读书和工作多年。2000年在美国佐治亚理工(Georgia Institute of Technology)求学。毕业后在一家美国公司做软件开发工作,从事企业级应用(Enterprise Applications)开发,主要负责服务器端框架的设计和开发,商业应用服务(Business Services)的开发, 和一些软件规范的制定。此外,我还有很强的人工智能和计算机网络方面的研究背景。
2、您开始做Tellurium这样一个自动化测试框架,是基于怎样的考虑呢?我看到有特色的两点是使用UI module-based这样的描述块来定义待测的UI,以及使用DSL来表述测试代码,还有哪些与以往框架不同的设计思想,缘起是什么呢?
在2007年,我们公司开始注意到Selenium测试框架。由于我们用敏捷开发方法(Agile development), 在Scrum队伍中,每个人的角色开始变得多样性了。我有个工作(Task)就是用Selenium去测试我们的一个应用程序(是用Dojo Javascript框架写的)。应该说在当时,Selenium是一个开创性的框架,如果用他们的复制和重播模式(record and replay)很容易产生测试脚本。但一旦我开始用Selenium,我发现它还是有一些缺点和不便之处。主要测试脚本是对代码的更新很脆弱 (Fragile). 但是在一个敏捷开发的环境下,一般都有阶段性的用户接受测试(User Acceptance Test), 由于程序一直更新,Selenium测试脚本的维护就变成一个很头痛的问题。而且,对于很多企业级应用,复制和重播模式本身就不太适用,比喻我们有很多数据格(Data Grid),它的内容本身就是动态的。其他的问题包括Selenium测试脚本不是结构化的,你可以看到处有XPath,这更增加了维护的困难。因此,我们决定开发一个在Selenium之上的框架来解决这些问题。我做的第一个版本是通过Spring框架和物体工厂(Object Factory)来产生UI元素(Element),使得框架能把UI元素的表达和测试代码分开,自动处理Javascript事件,并在一定程度上能处理动态网页内容。
由于这个框架用XML来配置UI元素,使用起来并不是很方便。在2008年,我用Groovy重写了整个框架并变成一个开源项目(open source project)。新的版本主要有三个大的改变。首先是采用UI Module(UI模块)描述块来定义待测的UI。这样做的好处是系统自动生成运行时的Locator,即使你改变了其中的一些元素,框架本身会生产新的 Locator来适应这种改变。而且框架侧重一个集合的元素,而不是单个元素,这样使得我们可以利用元素之间的关系来帮助我们定位他们在DOM中的位置。此外,这样也增加了重用性,比如,我们可以定义一些Tellurium Widget,在你的测试代码中可以直接定义这个Widget,而不需要重新定义一个个的单个元素。第二个大的变化是用DSL来写测试代码。这样增加了表达性使得用户很容易写和维护测试代码。Tellurium测试代码可以用Java, Groovy, 或纯DSL脚本来写。Tellurium本身也支持JUnit和TestNG测试框架。另一个大的变化是开始用UI模板(UI templates)来表述动态网页内容,例如数据格(Data Grid)。这样使得Ajax应用程序的测试变得可行和容易。
3、 Tellurium主要有那些子项目构成?
Tellurium主要是由Tellurium Core, Tellurium Engine, Tellurium Widget Extensions, 和Tellurium UI Module Plugin(TrUMP)子项目构成。Tellurium Core主要是处理DSL和动态生成Locator. Tellurium Engine是测试驱动模块,目前还是利用Selenium Core. Tellurium Widget Extensions包括一些DOJO和ExtJS Javascript框架的可重用Widget模块。这些Widget被编译成一个jar文件方便用户调用。TrUMP是一个Firefox plugin来自动生成UI Module。
另外,Tellurium还提供两个参考子项目(Reference Projects),分别为JUnit和TestNG项目,来给用户示范如何创建Tellurium测试项目和如何使用Tellurium的各种功能。
除此之外,Tellurium还提供了Tellurium Maven Archetypes,使得用户可以用一个Maven命令就可以创建自己的Tellurium测试项目。
4、介绍一下Tellurium的代码贡献者们吧?
我主要是负责Tellurium的整体设计和很大一部分的代码编程。除我之外,现在还有四个来自美国和英国的队友(team members)。Vivek Mongolu主要负责TrUMP的UI设计和实现。Matt Senter主要负责Maven支持,包括代码的编译,发布,和Maven Repository的维护。Haroon Rasheed参加了Tellurium参考项目(Tellurium Reference Projects)的开发,Selenium Grid的支持和其他的维护工作。Mikhail Koryak参于了TrUMP的开发工作,他是jQuery方面的专家,负责Tellurium的jQuery支持。现在参与Tellurium Engine的开发。
5、你了解在自动化测试工具这个领域,有着哪些和Tellurium类似的竞争对手吗?比如ThoughtWorks的Twist?与它们相比,Tellurium的优势在什么地方?有什么劣势吗?
Tellurium脱胎于Selenium,它的主要竞争对手还是Selenium, 毕竟Selenium已经推广好几年了。要用户用一个新的框架是要花一定的时间的。此外Canoo WebTest也是一个比较流行的网页测试框架(Framework)。但是Tellurium还是有它本身的优势的,如UI Module的概念,鲁棒性好,可重用性好,表达性好(Expressiveness)。用Tellurium写的测试代码的结构性好,比较容易维护。
毕竟Tellurium还是一个新的框架,到现在只有一年多的开发时间。有些特色还有待成熟。此外,Tellurium要用到Groovy动态语言,尽管用户并不一定需要了解Groovy才可用Tellurium,但由于Groovy相对比较新,所以不少人还是有疑豫的。
ThoughtWorks的Twist基本上是Selenium + GSpec, 就是在Selenium之上增加了行为测试(Behavior Driven Test)的DSL。其实我很早就考虑到对行为测试的支持,但精力有限,Tellurium目前还没有这方面的实现。将来会增加的,可以和EasyB框架结合来支持行为测试,或直接实现对行为测试的支持。
6、现在Tellurium的应用情况是怎样的?来自使用者的反响如何?
现在已经有不少Tellurium用户,主要来自美国,印度和欧洲。由于Tellurium本身的特色,如易用,可维护性好,新的功能如对jQuery Selector的支持,使用者的反应还不错。甚至有的用户在自己的公司里给同事作Tellurium的培训。当然,Tellurium还很年青,而且前一段时间由于全球性经济危机的影响,我们对Tellurium的推广还做得很不够。以后会加大对Tellurium的推广。
7、Tellurium在社区采用了哪些方式和开发者们进行交互呢?
我们有自己的用户组Tellurium user group, 用户提出问题往往能很快地得到解答。我们也有LinkedIn用户组让用户之间能更好地交流。此外我们还鼓励用户参加Tellurium的设计讨论和推广。我们会每年从用户中推选出一个最活跃用户(most active user)和一个最有价值用户(most valuable user)。Tellurium将来会设推广队(Evangelism Team),如果某人对Tellurium做了很多推广工作,他/她也可以成为Tellurium正式成员(team member)。
8、Tellurium未来的发展有怎样的规划吗?有计划推出中文的社区及文档吗?
尽管Tellurium和Selenium在概念上有很大的不同,一直到Tellurium 0.6.0, 我们还是依赖Selenium Core作为底层的测试驱动Engine. Tellurium 0.7.0将成为Tellurium发展史上的一个重要里程碑,我们将开发自己的测试驱动Engine使得Tellurium能更好,更有效地支持UI Module,同时可以进行UI Module的缓存(Caching)以增加其可用性和提高测试速度。并可对UI Module进行部分匹配以增加其鲁棒性。在新的Tellurium Engine的支持下,Tellurium widget将变得更容易,更实用,和更有效。其他的发展规划包括TrUMP的改进,行为测试(Behavior Driven Test)的支持,功能测试(functional test)的增强支持, 和IDE的支持。
毕竟我来自中国,当然希望得到更多的来自自己国家的用户的参与和支持。现在我们已经开通中文社区和文档项目,会有相关的中文文档逐渐添加进来,我们也热烈欢迎更多国内的开发者能加入进来,帮助支持和推广Tellurium,谢谢。
9、能给国内的用户一个快速的开始吗?怎么立刻感受到Tellurium带来的好处?
我们提供了一份中文版的Tellurium QuickStart,还有一个短小的演示: 十分钟感受Tellurium (10 minutes to Tellurium)。它包括利用Tellurium Maven archetype去建立一个新的Tellurium测试项目,再用 Tellurium Firefox plugin TrUMP去自动生成一个UI Module,然后再写自己的Tellurium测试代码。
如果用户不熟悉Maven, 他可以下载Tellurium参考项目(Tellurium Reference Project). 这个项目是我们用来测试Tellurium项目网页的。包括了各种例子,可以直接运行。
更多有关Tellurium的信息,请参考DZone上的相关资料和Tellurium的Wiki。敬请期待Tellurium在InfoQ中文站的更多技术文章。
原文载于:http://www.infoq.com/cn/articles/tellurium-testing-framework
反复的测试
开发者在迭代过程中会不断发布新的功能,也会不可避免的出现回归问题,即完成的新功能因为模块间关联紧密解耦不足,造成早前完成的功能因为新代码的引入而出现bug。如果缺乏一定的配合和思考,测试人员很容易就陷入到枯燥的反复测试泥沼中。
这样问题的原因可以追溯到软件架构设计时,没有很好的解决模块设计问题而埋下了祸根,无形中造成了测试和修复的成本提升。这对开发者是个很高的要求,当然如果真的能达到完美设计,那也许就不需要那么多测试人员和那么长的测试周期了。
可惜的是,这样的理想之国是不存在的,bug不可避免,于是有了回归测试这个概念和阶段。但在不停的迭代开发和测试中,回归测试的时机和粒度仍然是值得商榷的。从现在的实践看来,正式的回归测试的时机一般选择在一两个迭代过后进行,在回归测试前开发的功能逐渐稳定下来,这是周期进行的,然后在最终正式发布前还会有一次更全面的回归测试,以确保覆盖到所有功能点的测试能基本通过。
那对于在某个迭代中,开发者可能引入的回归bug,测试人员该如何来发现呢?这里就不得不提自动化测试在敏捷测试迭代开发过程中的重要性了。成熟而稳定的自动化测试,可以覆盖到已经完成的功能,进行反复的自动测试无需人工干涉,这样也可以讲测试人员从枯燥无聊的 重复测试中解脱出来,去做更加有价值的探索性测试。
测试能够敏捷吗?
开发敏捷了,测试也想敏捷,结果有了“敏捷测试”。但测试真能敏捷吗?
我一直认为敏捷是以开发为中心的,如果敏捷宣言尚且是对传统软件开发模式原则上颠覆的话,那么敏捷所带来的N多最佳实践更是以开发过程改进为目标的,信手拈来的就是TDD、CI、XP、PP等诸多实践方式,就是跟测试拉上一点关系的UT和Acceptance Testing也是多由开发者自己来完成,那对专业测试工程师来说,当团队进入到Agile的环境后,会有怎样的不同遭遇呢?在Agile中如何到测试更有效呢?
测试在敏捷前后的不同
在敏捷环境中,测试可以早介入,从确认客户需求开始,到测试计划、测试案例、测试执行、缺陷跟踪、回归测试,一直到最后软件系统发布,测试会贯穿在整个流程中,这是明显区别于传统的瀑布型模式的。这样的优点毋庸置疑,让测试专家从客户的角度尽早的使用软件,及早发现与需求相悖的问题,尽量减小因设计实现所带来的缺陷问道所招致的维护成本。
这样的描述会在所有“敏捷测试”相关的国内外资料中都能看到的,也是为大家所承认的。但具体问题具体分析,在不同的团队构成、不同的软件系统等条件下,所谓“敏捷测试”总不得不去面对一些棘手的问题。
测试在敏捷中的困境及对策
虽然测试工作的内容无非包括计划、执行、回馈等几个环节,这在进入敏捷环境后也不会有怎样的变化,但面对采用了诸多开发最佳实践的开发者以及会产生快速迭代出新功能的软件系统,测试人员如何保持快速的响应,并实时地调整测试过程,是每个测试团队不得不面临的问题。即使是“敏捷测试”的推广者们,在宣扬了测试早介入之后,也鲜有值得推介的测试实践拿出手来。这对各个测试团队无疑是个考验,即使是采用了相同敏捷实践的开发者也不会表现出一样的生产力,只有测试工程师根据整个团队的特点,总结出一套最适合团队的测试模式,才是最理想的。
系统测试
不得不说的是,就算是“敏捷测试”也没有考虑到系统测试在敏捷环境中怎样做。这对一般不会太看重软件性能和集成性的系统来说不算个大问题,但对具有大大小小系统性能测试需求的测试团队来说,是不可想象的。测试早介入,在系统测试团队看来似乎是场噩梦,对尚未稳定的架构施加系统性能测试,多半会引起系统测试工程师们徒劳无功,因为开发人员这时不会太介意性能上的问题,他们有更重要的功能还没实现,但schedule如此紧张。如果中途需求变化甚至架构变化,开发者几乎可能把设计实现全部推到重来(这也是拜敏捷所赐了)。那之前系统测试工程师花费大量精力和时间,发现的问题很可能就此不可重现不再有效。相对白白付出的工作量,如果这段时间用来做技术调研准备和自动化测试开发,效益不可同日而语。这里需要开发团队和系统测试工程师相互配合,开发为测试定义一些系统测试的进入点,并及时对系统测试的defect作出响应,才是理想的行为。
分布式团队
敏捷专家推荐开发测试工程师们坐在一起工作,这样交流更加方便直接,减少沟通成本,这在软件快速迭代、快速响应需求变化的过程中是相当重要的。每天有scrum,有defect可以快速交互。但这在分布式团队中很难实现,两支不同时区的团队没有重合的工作时间,开会时间安排成了问题,如何把各自团队自己的scrum结果让另一方也知道呢?除了从分配story方面尽量减少两支团队的story依赖和耦合外,就是需要采用一些特定适合的方式来解决。如果能克服时差,一块scrum是最好的。不行的话,可以通过scrum mail每天互相交换更新的状态。
迭代测试+自动化测试
每个迭代都会有一些新的功能被开发出来,如何制定计划既保证这些新功能的测试,又保证新功能或者defect的修复不会导致已有功能遭到破坏呢,这里有一些策略。首先是功能开发的迭代计划,项目经理需要仔细考量不同的story在各个迭代之间减少依赖和耦合,软件架构设计者也需要有同样的考虑,这里有软件可测试性的问题。这样在测试人员介入后,不会发生牵一发而动全身,顾此失彼的问题。
另外就是在软件系统随着迭代的不断进行,累加的功能越来越多,测试资源有限,不可能一直全面地测试到软件系统的所有方面。除了前面提到的不同迭代的软件交互很少依赖和耦合外,自动化的测试是保证不断迭代后继续保证软件质量的不可缺少的途径。自动化测试开发,这是另外一个话题,如果认为这全部只是测试工程师的责任,那就是短见和无知了。自动化测试要求软件系统开发者能够在UI上预先提供一些钩子,供自动化测试开发工具抓取UI对象进行识别并操纵,完成模拟用户的实际操作。如果这方面的软件可测性也无法保证的话,测试脚本维护成本居高不下,影响软件质量,除了测试工程师叫苦不迭之外,最终仍然会形成很多defect送到开发者的面前。所以,这是整个团队的责任。
缺陷管理
软件开始正式的迭代开发后,由持续集成所产生的软件交付成为测试工程师的工作目标,但如果一些功能还没有完全实现就因此产生了defect,测试工程师把它们记录在缺陷跟踪系统里面,越积越多,测试工程师据此为自己的工作量体现,姑且不说这对软件质量没什么意义,在功能实现彻底完成之后,之前的这些defect中的大多数就会自行解掉设置无效,那么测试人员所做的又是大量的无用功了。需要时刻牢记在心的是,最终目标是软件质量的提升,而不是defect的数量。测试和开发足量的沟通交流,足以消除掉大多数无谓的defect,只有那些已经完成的功能跟软件需求还相悖的话,才是真实有价值的defect,值得记录值得跟踪。
这里有一篇好文:扔掉bug跟踪系统,深得我心。
团队观念
说到底,“敏捷测试”需要的是一支紧密协作的团队,开发和测试工程师互相配合,充分沟通交流,为提升软件系统的质量致力工作,不在意无谓的defect数量,减少功能模块间的耦合依赖,提高软件可测试性,合作开发自动化测试脚本。其实根本无需太较真在“敏捷”这个字眼上,更重要的是改进出最适合自己团队的软件开发测试模式。

最新评论