浅析基于Selenium和TestNG的自动化测试框架

发表于:2017-9-13 15:24

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

 作者:张月秋    来源:点融黑帮

  导语:
  互联网产品迭代迅速,敏捷开发模式逐渐盛行,敏捷开发模式下的敏捷测试需要采用更敏捷的测试流程,在敏捷测试中回归测试所占的比重越来越多,而自动化测试是快速实现回归测试的有效方法。一个项目中自动化测试是否能有效的开展,自动化测试框架是关键所在。因此,如何构建稳定的、易复用、易扩展的自动化测试项目对于敏捷测试有重要的意义。
  1面临的挑战
  目前互联网金融火的一塌糊涂, P2P平台的开发测试项目正在如火如荼的进行, Web应用因为其迭代周期短,需求变化快等特殊性质,越来越多的Web开发团队在拥抱敏捷。同时随着前端技术JavaScript,Html5,等不断被推出和完善,Web应用也变得越来越复杂很绚丽。这都给我们的测试带来了挑战。
  ①持续变化的需求导致反复的回归测试
  ②复杂的UI(各种JavaScript的插件,Ajax等)
  ③往往一个测试团队需要应付多个项目的测试工作
  ④非常有限的资源(人力,成本,等等…)
  ⑤跨平台(Linux,Mac,windows),跨浏览器(Firefox,Chrome,IE)
  ⑥P2P行业的特性,充值提现利息等后台业务数据正确性的验证非常复杂
  2如何解决
  针对前5个问题,ThoughtWorks公司推出的开源Web自动化测试工具Selenium给我们带来了解决之道。Selenium基于JavaScript并结合其WebDriver来模拟用户的真实操作,它有很好的处理Ajax的能力,并且支持多种浏览器(Safari,IE,Firefox,Chrome),可以运行在多种操作系统上面。
  对于第6个问题,则需要UI测试结合接口测试,项目后台主要是基于HTTP协议的restful应用,可以采用spring mvc测试框架通过服务端测试和客户端测试来解决。下文重点阐述笔者在使用Selenium WebDriver+TestNG测试框架解决前5个问题UI自动化测试的使用经验和思想。
  话说Selenium只是帮我们解决了执行层面的问题,在大规模的自动化测试项目中,我们还需要一个基于Selenium平台的测试框架,这个框架需要有以下的特性。
  √ 对象库的分离和管理
  √ 支持数据驱动(DDT)
  √ 自动化测试脚本的组织和管理
  √ 脚本的可重用(团队)和可配置
  为实现上面的需求,可以参考Google内部使用的一个基于Selenium的Web自动化测试框架Ringo,如下图所示,从Ringo的架构中可以看出,Ringo实现了数据,对象,操作的3者完全分离。并且对于一些公共的脚本进行了抽取和重构(SeleniumHelper),代码的复用率非常高。所有的测试用例都是可配置化。
  3框架思想
  可以参考上面的框架通过对Selenium进行二次开发并结合TestNG实现数据驱动和高度可配置化,并且具备很好的对象库的管理的功能,做出一个比较成熟的测试框架。这里不包含实现DataGenerator,测试数据随机生成还有待研究,只讨论从数据文件读取测试数据。
  首先我们可以通过对selenium提供的API方法进行二次封装来避免每次对这些方法的直接调用,通过方法的封装可以防止重复编写常用方法,还能实现复用,并且易于维护。
  接着对这些方法类进行分层组织,而不是统统的堆到一起。比如分为Page类Window类,Element类,Action类等。
  然后按照MVC模式的思想将测试项目分模块,以便控制与数据与测试用例分离,在对象包中放入所有测试用到的页面包括Page类和Window类,Element类,在数据包中放入各个页面的元素信息文件,即其ID,XPath等信息,还有测试数据。在用例包中放入测试用例的内容。 
  4框架实现
  4.1对象库的分离和管理- Page类和Element类
  对象库包括页面对象和元素对象,比如zhihu的登陆页面是一个页面对象,每个页面的元素,也可以封装成一个个元素对象。如果你封装了页面,封装了元素,再封装一个对应的登陆Action,你的每个测试用例是调用的login.action()。这样,你只需要改变你对象库的内容就完美解决UI变化,而不必一个个修改测试用例。
  Element类:
  Element类就是我们常用的driver.findElement()的形式,就是元素类,什么是元素类呢?元素就是我们需要定位的那些东西,我们在操作过程中很难知道一个findElement到底查找的是什么,因为所有的标签形式都是通过id,xpath或者各种各样的定位方式来实现的。
  如果把各种各样的findElement都统统的放在一起,造成的脚本难以理解让后续接手的脚本开发人员可能头疼不已,所以要进行元素查找的封装。
  Element类提供了所有的关于element的方法,比如鼠标事件和键盘事件,还有更重要的元素定位方法。定位的方法在这里不做任何的推荐,因为每个人的思路不同,实现的方式也不同,我比较偏向的做法是做一个property文件来进行资源的管理,把所有需要的资源都放入到property里面,这样我们就可以进行元素的定位了。并且在后期维护中主要维护property就可以进行对整个脚本进行维护了,不需要我们大量的重新进行源码的分析和修改了。
  当然设计有优化过程,我们可以通过map的方法作为属性值来进行元素的管理,他的各种定位方法存放在map中,我们需要的时候只需要调一下就可以了。
  其实通过xpath的方式我们就可以基本上定位大多数的元素。剩下的内容就是我们对element内容的扩充了。我们可以把元素的更加具体的抽象出来,比如我们把select,table,checkbox等等等的各种html标签元素显式的定义出来,在我们定义一个元素的时候我们能够更加清晰的看到这个元素的含义,我们知道它是一个按钮或者table等等等。
  Page类:
  我们知道pageObject的思想是把资源都放入到我们定义的page类里面,所以这个时候我们需要思考了,我们如何设计这里的page类呢?按照pageObject的思想来看,page类应该是我们自己编写的,那样我们的框架是不是就可以放弃编写page类了呢?直接封装一些通用的方法?显然是不对的,对于页面html源码操作的过程中,我们烦透了这些元素查找的硬编码方式,在一个case里面或者两个case里面反复的调用编写是让人头疼的一件事情,所以我们可以把所有的单页面看做一个层次,里面和PageObject的思想一样,就是放入了通用的方法,比如获取title,元素是否出现,某些action等.可以把page类当作一种资源来处理,我们所有需要的东西都是通过page来获取的。
  封装对象还应包括Driver类和Brower类,之前的点融黑帮文章有过介绍不再累述。
  接下来以这个登陆为例。
  首先封装一个BasePage的类,毕竟所有的页面都有共同的东西,每个页面都有元素,每个页面元素都有相应的方法,比如type,click,getElement,isElementPresent,getLocator等。这里不再贴图占用篇幅。
  接下来封装元素,Webdriver的元素,每个元素都有相应的定位地址(xpath路径或css或id)等待时间和定位类型,默认为By.xpath。
  接下来就是登陆页面的类
  接下来就是登陆的action
  进入用户中心的action
  到此为止,已经封装完毕。接下来就能在测试用例直接调用着。
  4.2其他类-数据参数化等
  我们使用QTP的过程中我们经常会用到参数化,我们自动化的设计都有了,但是没有参数化的功能怎么办?我们应该先想象一下数据提供的方式。TestNG提供了一种参数化的形式,但是它是需要在xml里面配置或者硬编码的形式来进行编写。不过它提供了一种DataProvider的方式来进行参数化,它传递参数的形式是Object[][],我们可能希望使用参数的时候通过excel表格来完成,这些都是可以实现的,poi包,jxl包提供了解析excel的功能,非常的强大。具体实现不再多说。
  通过这些层次的分析我们已经出现一个框架的雏形了,然后我们剩下的设计就是基于完善和优化了。比如test case运行结束的结果报告和分析,日志的实现等。
  5小结
  在这里我们只讨论前端自动化的设计,不讨论接口自动化,单元自动化,服务端测试。个人能力水平很有限,可能很多地方说的不到位,请多包涵。希望能够通过这篇文章抛砖引玉,能够给那些希望学习自动化,希望编写小测试框架的童鞋,一点点的启发。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

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

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

沪ICP备05003035号

沪公网安备 31010102002173号