在本系列的第一篇文章“我们的测试为什么不够敏捷”中,根据实例总结出敏捷自动化的两大阻碍:“脚本维护困难”、“断言条件繁琐”。本文针对如何降低脚本维护难度分享一些实践经验。
近几年,Web技术发展势头迅猛,浏览器市场群雄争霸、各种UI组件库也如雨后春笋。现在互联网上已经很少有仅支持一种浏览器,并且不基于任何可复用的UI组件库进行开发的应用了。开发人员基于各种优秀的UI组件库(如,JQuery、Dojo、ExtJS)可以很容易的开发出功能强大、展现绚丽、兼容各种浏览器的页面(如下图):
UI组件库的广泛采用在提高开发效率的同时,也极大的提升了用户体验。基于UI组件库之所以能快速开发出功能强大的页面,是因为UI组件库可以自动生成海量、结构类似的HTML源码(如下图):
开发人员是幸福的,因为这一切对于他来说完全透明。于是只剩下自动化测试人员独自面对这样“恐怖”的页面源码。
如前文“我们的测试为什么不够敏捷”中所言,业界常见测试工具的脚本本质上还是针对页面源码的,因此原本就举步维艰的自动化测试在开发使用UI组件库之后变得雪上加霜:
- 页面DOM结构非常复杂
导致所录制/编写脚本的复杂度变的更大、可读性变得更差。
- UI框架的升级很可能会导致DOM结构的变化
因此即使开发人员没对代码做任何改动,测试脚本也会因为UI框架的升级变得无法回放。
- 控件ID是自动生成的,甚至在每次刷新页面后都会变化
大部分自动化测试工具在“录制”脚本时,都会优先使用ID定位策略,自动生成的ID会导致这种关键的控件定位策略变得无效。
- UI框架在各种浏览器下自动生成页面源码可能不完全相同
为了在不同浏览器下“看起来一样”,实际的DOM结构有时也可能是不同的,因此所录制脚本的浏览器兼容性会比较差。
技术的发展是为了让生活变得越来越轻松。从用户的角度来看确实如此:Web应用的功能覆盖范围越来越广、操作越来越方便、界面越来越美观。
为什么自动化测试人员没有感觉工作变得轻松呢?
要回答这个问题,首先要分析“用户使用软件”与“自动化测试软件”之间的一些重要差异:
- 用户使用软件时只关注界面上能“看”到的,而不用总是“查看页面源码”;
- 用户会更关注整体业务的正确性、稳定性,而不仅仅是每个孤立页面功能的正确性;
- 用户对页面样式、响应时间、浏览器兼容性要求越来越高; 如果我们能像用户使用软件一样进行自动化测试,测试就会变得更敏捷:
- 根据界面快速编写测试脚本:敏捷应对需求的变化;
- 降低对技术实现(UI框架、页面样式/布局)的依赖:敏捷应对设计/开发的变化;
- 测试脚本可以稳定支持各种浏览器:敏捷应对环境的变化;
(一)根据界面快速编写测试脚本的实现思路
还是以前文“我们的测试为什么不够敏捷”中用到的“用户增加”界面为例:
如果你是作为用户在使用上述功能时,心里一定也会默念下面内容吧:
“账号”输入***、“密码”输入***、“姓名”输入***、“性别”选择***、“生日”输入***、“国籍”选择***,点击“保存”按钮。
这就可以理解为“根据界面编写的测试脚本”。
我们在使用Web应用时,心里常常默念的还包括:“展开/收拢/选中”树(Tree)的某个节点、数据表格(Grid)的下一页/上一页、选中数据表格(Grid)的某一行、点击/关闭某个Tab页,等等。
很多人在与笔者交流的过程中都会问“为什么还要手工编写脚本,怎么不提供脚本录制工具呢?”
因此在这里想澄清一下大家对“编写”脚本的误解,与传统自动化测试工具相比,“此脚本”非“彼脚本”。
传统的测试脚本是给特定测试工具执行时使用的,对人类而言可读性极差,更别谈手工编写了,因此“录制/回放”工具往往都是必备组件。即便如此,此类“录制/回放”工具的实际使用效果,也是不尽如人意的。
从这种角度来看,“录制”脚本是“下策”,“上策”应该是让测试脚本大幅简化,并且具备良好的可读性和可维护性,以达到人工编写很容易的程度。
——以上只是笔者的一点差异化见解,对业界优秀的测试工具没有任何冒犯之意!
(二)降低测试脚本对技术实现依赖度的实现思路
Web页面开发中的技术实现细节主要包括UI框架的选择及版本升级、页面样式设计、页面布局设计,因此我们的主要目标就是降低测试脚本对这些因素的依赖。
为了便于测试脚本的解析和组织管理,目前还不能直接写形如“点击(保存)按钮”这样的纯自然语言,但可以设计成接近自然语言的领域专用语言(DSL:Domain Specific Language),本文采用XML来实现这种DSL。比如:
<event id="[button]保存" name="click"/>
这种超级清晰、简短的测试脚本与实际海量的页面源码之间有一条鸿沟,我们可以通过“封装”来屏蔽。下面以ExtJS的Button控件为例来示意如何完成这种封装:
- Button的界面展现如下:
- 实际生成的页面源码DOM结构如下(省略部分非关键属性):
<div id="button-1032" class="x-btn x-box-item x-btn-default-small x-noicon x-btn-noicon > <em id="button-1032-btnWrap"> <button id="button-1032-btnEl" class="x-btn-center" autocomplete="off" role="button"> <span id="button-1032-btnInnerEl">Cancel <span id="button-1032-btnIconEl" class="x-btn-icon "/> </button> </em> </div>
我们封装所要做的主要工作就是解析出测试脚本中定义的关键信息(button、保存、click),结合对应页面源码的DOM结构,翻译成W3C标准的定位方式(如,XPath)。通过XPath就可以定位到页面上的任何控件。
对于测试脚本(<event id="[button]Cancel" name="click"/>),翻译后的XPath可以是(//button/span[text()='Cancel'])。
同理,其它测试脚本还可以包括:
- 树节点展开/关闭
<event id="[treeNode]部门" name="open"/><event id="[treeNode]部门" name="close"/>
- Grid翻页
<event id="[grid]人员列表" name="nextPage"/>
它们的封装实现比Button稍微复杂一些,但原理是一样的。
(三)增强测试脚本浏览器兼容性的实现思路
这个就比较简单了,只要选用标准化程度高、厂商支持度高、扩展性强的第三方底层实现即可,笔者推荐采用Selenium WebDriver。
通过上面的介绍,有些读者或许会有个疑问:“如果一个Web应用没有采用任何UI框架、而且编码又极为不规范,那么你这种方案岂不就不适用了?”
答案是肯定的。但笔者认为此类Web应用如果想要发展下去,其瓶颈还停留在开发环节,对其进行自动化回归测试的投入产出比不是很大。
此外,为了进一步提高Web应用的可测试性,笔者在实际工作中总结了一些前台页面开发的最佳实践,供大家参考:
- 页面采用单帧实现
如果页面上的frame/iframe嵌套很多的话,控件的定位会比较麻烦,并且影响展现速度。
- 兼容Firefox
Firefox有很多强大插件,如Firebug、FirePath,非常有助于在开发、测试过程中的调试问题。
- 采用统一的UI框架开发复杂控件
对于复杂控件,比如Tree、Grid,如果不基于统一的UI框架实现,开发、测试工作量都会很大。
- 对于需要设置ID的控件,一定要设置唯一、并且有业务意义的ID
当然对于一般不需要设置ID的控件(如,div)或者控件ID由UI框架自动生成的情况除外。
- 对于Form中最常见的label+input组合,尽量让label和input有逻辑对应关系
推荐为label设置for属性,属性值等于input的id,这样对最终用户也比较友好:双击label的时候,鼠标焦点能定位到对应的input中。
- 页面设计时考虑用户体验,往往用户使用方便的时候,自动化测试也会方便
比如,一个页面上不要有多个同名的按钮、通过点击上下微调按钮(箭头)改变输入域值的控件也支持直接输入值、日期选择控件支持用户直接输入、下拉列表控件支持输入过滤,等等
对以上几点最佳实践有如下补充说明:
- 这些最佳实践不仅能提高Web UI的可测试性,也非常有助于提升用户体验;
- 这些最佳实践如果能满足更好,即使不能全部满足,也可以开展自动化测试;
按照本文给出的方案,前文“我们的测试为什么不够敏捷”中用到的“用户管理(增加、删除)”功能的自动化测试脚本就可以改造为如下样式(示意代码):
- <event id="[button]新增" name="click"/>
- <event id="[input]帐号" name="setValue" value="${account}"/>
- <event id="[input]密码" name="setValue" value="1"/>
- <event id="[input]姓名" name="setValue" value="${accountName}"/>
- <event id="[input]性别" name="select" value="女"/>
- <event id="[input]生日" name="setDate" value="1980-01-01"/>
- <event id="[input ]国籍" name="select" value="中国"/>
- <event id="[button]保存" name="click"/>
- <event id="[gridRow]${account}" name="assertExist"/>
- <event id="[gridRow]${account}" name="check"/>
- <event id="[button]删除" name="click"/>
- <event id="[ gridRow]${ account }" name="assertNotExist"/>
以上测试脚本完全基于界面上“可见”的内容进行编写,大家应该不需要看下面的解读,也能明白脚本的意思:
- 第1、8、11行表示点击“新增”、“保存”、“删除”按钮;
- 第2~7行表示为输入域赋值,赋值方式有输入文本、输入日期、选择下拉选项;
- 第10行表示选中表格中的指定行,即,选中指定行前面的Radio按钮;
- 第9、12行表示断言表格中指定的行“存在”或“不存在”;
- ${ account }表示使用外部的变量account;
自动化测试中最关键的两部分是“脚本”和“断言”。至此,自动化测试脚本的编写、维护以及执行已经可以跟上敏捷开发的步伐了。本系列的下一篇文章会就“如何让断言不再成为自动化测试的负担”这个话题来分享一些实践经验,敬请关注!
作者简介
殷坤,东软集团资深测试经理、技术讲师,10年软件研发、实施、测试及项目管理工作经验。 目前专注于敏捷项目管理及质量控制、过程改善、自动化测试、持续集成、用户体验提升等方面。
原文地址:
http://www.infoq.com/cn/articles/Agile-test-automation-2
相关推荐
敏捷开发强调快速响应变化、用户参与以及持续交付可用软件,其中自动化测试作为确保软件质量的重要手段之一,在敏捷开发过程中扮演着不可或缺的角色。 #### 二、软件质量漫谈 在讨论自动化测试之前,我们首先需要...
《工商银行IT研发自动化升级探索——核心批量架构转型与测试提升》这一资料主要涵盖了银行业IT研发领域的重要议题,包括核心批量架构的转型以及自动化测试的提升。以下是对这些知识点的详细阐述: 1. 核心批量架构...
随着敏捷和DevOps的兴起,测试人员的角色也在不断演变,如持续集成和持续部署(CI/CD)中的自动化测试角色。 总之,软件测试是一个涵盖广泛领域的专业领域,它对于软件开发的成功至关重要。无论是新手还是经验丰富的...
### 自动化测试——敏捷测试的基石 #### 摘要 段念,Google中国高级测试经理,拥有多年软件开发及测试经验。他在软件测试的技术和管理方面有着独特的见解,并在软件测试团队管理、自动化测试、性能测试以及开发测试...
2. **自动化测试**:利用自动化测试工具可以显著提高测试覆盖率和速度,但需谨慎选择,确保其符合项目需求,并对团队进行充分培训。 3. **回归测试**:每次代码变更后都需要进行回归测试,以验证修改未引入新的问题...
在软件开发过程中,软件测试是不可或缺的一环,它与软件工程...随着技术的发展,测试自动化、持续测试和敏捷测试理念逐渐成为现代软件开发的标准实践。理解并掌握这些知识点对于任何软件开发团队来说都是至关重要的。
《敏捷自动化建模——一种用于城市规划自动设计和生成的新型地理计算方法》这篇文档,主要探讨了在当前快速发展的城市化进程下,如何利用先进的计算技术优化城市规划,提高设计效率和精度。本文将深入剖析该主题,...
传统的手工测试方法已经难以适应现代软件开发的速度和规模要求,因此自动化测试技术应运而生,并迅速成为提升测试效率和软件质量的有效手段之一。 #### 二、面临的挑战与问题 尽管自动化测试能够显著提高测试效率...
【Selenium+TestNG自动化测试】是现代软件开发中一种高效的质量保证手段,尤其在云计算领域,如阿里云,自动化测试能显著提升测试效率和软件稳定性。自动化测试通过编写可执行的测试脚本来模拟用户行为,对软件进行...
朱少民的资料可能会涵盖自动化测试工具的使用,如Selenium、Junit和TestNG等,以及如何编写和维护测试脚本。此外,持续集成和持续交付(CI/CD)也是现代测试技术的一部分,它们能加速软件开发流程并确保质量。 4. ...
这份"企业内部绝密资料——软件测试"是一份全面的培训教程,专为企业内部员工设计,以提高他们的测试技能和专业素养。 一、软件测试基础 软件测试是对软件产品进行系统性的检查,以验证其是否符合预定的需求或规格...
2. 自动化测试:使用工具如Selenium、Junit、Appium等提高效率和准确性,尤其适用于回归测试和持续集成。 3. 白盒测试:了解代码结构,从内部逻辑进行测试。 4. 黑盒测试:不考虑内部结构,仅根据功能需求进行测试。...
敏捷自动化建模是一种新型的地理计算方法,主要应用于城市规划领域,通过自动化技术进行城市设计与规划。这种方法通过利用加权决策树整合多个决策参数,以实现城市的综合用地开发潜力分析。在分区规划方面,通过自动...
**模型驱动的自动化测试用例生成工具——AutoTCG** AutoTCG,全称为Auto Test Case Generator,是一款专为软件测试领域设计的自动化工具。它采用模型驱动的测试方法,帮助用户通过业务流程模型来生成测试用例,旨在...
5. **质量管理**:通过持续集成和自动化测试,MSF确保软件的质量得以持续提升,避免了后期修复大量错误的高昂成本。 6. **沟通与协作**:MSF鼓励团队成员间的透明沟通,通过定期的评审会议和反馈机制来改进工作流程...
通过结合敏捷开发的最佳实践和自动化测试技术,SCAF不仅提高了测试效率,还降低了人工错误的风险,最终帮助开发团队更快地交付高质量的软件产品。未来,随着自动化测试技术的不断发展和完善,此类框架将在软件开发...
其次,自动化测试工具的使用是现代软件测试的一个重要组成部分,如Selenium、JUnit、Appium等。这些工具可以提高测试效率,减少人工错误,并且适应快速迭代的开发环境。考生需要掌握至少一种自动化测试工具的使用,...