51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1544|回复: 0
打印 上一主题 下一主题

如何提高UI自动化测试的质量

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2018-4-24 15:40:08 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
背景

      项目是基于Ruby on Rails开发的web程序,应该说项目中的测试实践是很好的,具有高覆盖率的单元测试
以及比较合理的集成测试。存在的问题是,所有的单元测试和集成测试都是针对后端代码的,前端的JavaSrip
t代码没有单元测试(这个是有历史原因的,暂时没法改变)。这也就意味着针对前端UI的修改是没有底层的
单元测试来保障的,只能依靠高层级的UI自动化测试和手工测试来保障。

      我们最近刚刚完成了一个story,是纯前端的开发工作,结果在上线后发现我们在修改页面模板文件时,
忘记了其他地方也在使用同样的模板文件,导致了部分页面样式错乱,甚至无法访问。这个bug在现有的UI自
动化测试和手工测试中都被遗漏了,直接发布到了产品环境上,后来通过线上日志才被发现。不得已我们只
好把版本先回退,修复bug后再重新上线,release的时间推迟了一周,可以说整个团队为此付出了严重的代价。

痛点

      作为团队的QA,出现这样的问题自然让我很不好受,颜面无光。。。抛开没有做story业务分析,手工测
试场景遗漏等问题,聚焦在现有的UI自动化测试上,以下是我感知到的一些痛点:

UI自动化测试的稳定性不高 - UI自动化测试是用ruby版本的selenium实现的,存在着众所周知的问题,例如
不够稳定,经常由于页面加载超时,UI交互复杂等问题导致测试失败,使得自动化测试结果的有效性不高,
失去了它本来应该具有的价值。

测试场景覆盖不够全面 - 当然,根据测试金字塔的理念,上层的UI自动化测试应该是小规模的,只覆盖基本
功能:


      但是具体到这个项目中,由于前端代码的底层测试缺失,所以不得不依靠高层级的UI自动化测试来覆盖
更多的场景,   最起码要能完成基本的回归测试,否则手工测试的压力太大。这就回到了第一个问题,正是
由于UI自动化测试的稳定性不高,所以我只实现了很小一部分功能,以免后续维护的成本太高,而我们遗漏
的bug恰恰没有包含在自动化测试的场景中。

问题分析

      所以,我们的聚焦点集中在了如何提高UI自动化测试的质量上,经过分析,主要的问题有:

页面加载时间超时

在用webdriver的方法访问页面时,经常出现加载超时的问题。页面的DOM结构已经渲染完成了,但是在访
问某些外部网站时长时间没有响应,导致测试脚本一直卡着无法继续进行,最后报超时错误。

页面交互action太多

UI自动化测试的一个缺点就是所有的执行动作都要通过页面的action来完成,例如文本框输入,点击按钮,
而且这些动作的执行结果存在太多的变数,导致最后写出来的测试脚本太过脆弱,很容易失败。

解决问题

使用异常捕获机制来处理超时等异常情况

      针对页面超时的问题,由于页面的DOM结构已经渲染完成了,所以其实可以继续执行后续的用例。但
是如果与外部网站的请求没有全部完成,selenium会认为页面加载没有完成,就一直卡在访问页面的get
方法上。我的做法是设定一个页面加载的超时时间:

dr.manage.timeouts.page_load = 30

      超过30秒就认为页面加载超时(经过测试,30秒的时间已经足够把页面的DOM结构渲染完成了),
然后访问页面时捕获超时的异常:

begin

   page.open_page

rescue Selenium::WebDriver::Error::TimeOutError

   puts "ERROR:page load timeout!!"

end

      这样如果加载超过30秒,会抛出异常后继续向下执行。不致于因为访问某些外部网站请求过慢,而
卡在页面加载的步骤,导致整个测试用例失败。同样的策略也可以应用在某些复杂或者不确定的执行结
果上,捕获可能出现的异常,提高测试的健壮性,避免非产品原因导致的测试用例失败。

减少UI测试,增加API级别的测试

这个观点听上去多少有点荒唐,提高UI测试质量的方法是减少UI测试。。。。但事实就是这样,UI测试
是自动化成本最高,最不稳定的测试,能够在低层级完成的测试,例如API层的测试,就不要放到UI层去
完成,这样会使测试更加稳定和健壮。很多页面action,例如提交表单,点击按钮等,实际都是向后台发
送了一条请求,如果测试的是功能,那么完全可以用API来完成这些测试。重点还是在于我们究竟想测什
么,是否必须要从UI层去完成这些测试?这就是测试结构的设计问题了,这里不展开讨论。

在这个项目中,我把一些可以在API层完成的测试从UI测试用例中分离出来,用ruby的Faraday库(当然
也可以用其他的,例如JS的SuperTest)调用相应的API并对返回数据做校验,这些测试相比于UI测试更
加稳定,运行速度更快,整个测试的稳定性便得到了提升。

将页面交互的action与静态页面内容分开测试

这个方法的思路和上一个类似,尽量减少通过页面加载和交互来完成的测试。如果测试内容中不包含动
态的页面交互步骤,例如只是想测试页面能否正常打开,某一部分的内容能否正常显示等,可以从页
面的DOM结构中通过校验某些元素来完成测试。

举个例子,如果想测试百度首页,可以不用从selenium webdriver中去加载这个页面,直接用ruby的Far
aday或者JS的SuperTest去访问"http://www.baidu.com"这个URL。这样拿到的将是一段html的文本,
然后再解析这段html文本(例如用ruby的Nokogirl库),获取对应的内容来做校验。例如返回码是200,
的内容是“百度一下,你就知道”,那么可以认为首页能够正常打开。<img>中的src属性是一个正确的
图片文件,可以认为百度的logo能够正常显示。

这里会产生疑问,如果我就是想测试界面怎么办?这就回到了刚才那个问题,我们究竟想测什么?如果
只是想测功能,那么我们就尽量减少对界面的依赖。如果只是想测界面,那么也有其他的办法来完成,
例如WebdriverCSS或者PhantomCSS等界面对比的测试工具。当然,有些测试步骤是必须要依赖页面交
互的,例如点击某个按钮打开一个新的对话框或者跳转到其他页面,这些测试就只能通过webdriver来
完成了。

总结

      通过实际的尝试,我明显感觉到优化后的自动化测试相比于原来有了更稳定的表现,运行速度变快,
非产品原因导致的用例失败次数变少。而且自动化测试更稳定后,我有信心去实现更多的自动化测试,
扩大覆盖的场景。我的一些感受和收获是:

  1.UI自动化测试的编码实现不难,难的是如何做整体的测试结构设计。在UI测试中覆盖的场景太少
达不到测试的目的,场景太多又会成为团队的负担,带来高昂的维护成本,需要和UT/API等测试综合考
虑,互相弥补。

  2.UI自动化测试是把双刃剑,它应该是QA最后考虑的自动化测试方法。只有当其他层级的测试无法
达到目的,或者希望测试的内容必须要通过UI完成时,再去考虑用它。低层级能完成的测试不要放在高
层级去完成,在静态DOM结构中能完成的测试不要通过webdriver加载页面去完成。


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-11-17 23:47 , Processed in 0.061569 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表