【IT168 技术】Selenium是时下很流行的面向web的自动化测试工具,它以执行效率高,覆盖的浏览器普遍等优势获得了不少人的亲睐。TestNG是一款测试 框架,它派生自JUnit和NUnit,除了继承了二者的优点以外,又额外的发展出了一些新的功能,让其更增强大和易用。文章会重点介绍 Selenium2结合TestNG如何作自动化测试,另外也会介绍ReportNG,它是对TestNG report的一个扩展,它相较于TestNG自身的report而言,更加美观和易读。javascript
利用Selenium实现web自动化测试的优点css
相比QTP,RFT昂贵的成本,做为开源工具的Selenium WebDriver天然不用多说。并且selenium是一款基于浏览器的测试工具,所以在响应UI请求时运行速度比较可观,能很好的节省运行时间,提升 执行效率。在与大多数测试平台的整合以及可扩展的脚本语言种类上(Java、dotNET、Perl、Python、Ruby、C#等)较之其余工具也有 很大优点,最后,Selenium 支持多浏览器操做(IE,Firefox,Safari ),这也是其余测试工具所不具有的,固然,没有什么万能的测试工具,在全面评估被测系统和测试需求后,合适的就是最好的;并且在作自动化测试过程当中,每每 不能只单独使用一种自动化工具,结合不一样自动化工具的优点来达到咱们的目的是最佳的实践。html
Selenium的进化java
Selenium已经从以前的1.0(RC)进化到了如今的Selenium2(Selenium1+WebDriver)。web
在运行Selenium1.0程序以前,咱们必须启动Selenium server端,也就是Selenium Remote control,咱们简称RC,RC主要包括三个部分,launcher,http proxy,selenium core, 其中selenium core是由一堆javascript函数构成,经过调用这些函数,来实现对浏览器的各类操做。既然已经能够实现对浏览器的操做,那为何还须要 Selenium2(Selenium1+Webdriver)呢? Selenium1主要存在如下几个缺点1.没有原生的鼠标和键盘事 件;2.XSS/HTTP同源数据问题;3.popup dialog问题。Webdriver对不一样浏览器的处理和Selenium1.0有着明显的不一样,Selenium1.0不论是什么浏览器,都是由 javascript来处理,而webdriver是选择浏览器最容易识别的语言来处理,好比在Firefox中javascript最容易,在IE中 C++最容易识别,经过灵活选择最容易识别的语言来处理多浏览器,咱们就能够很好的回避某些浏览器对javascript的安全限制,Webdriver 不只能够处理这方面的问题,并且能够调用操做系统API,尤为是当用户须要模拟鼠标或键盘操做时,这项能力的做用表现的尤为明显。经过对比, 看来从Selenium1.0进化到Selenium2.0仍是颇有必要的。浏览器
利用Selenium web driver实现自动化测试安全
为了让整个文章更加充实,做者以一个简单的Scenario为例,来一步一步告诉读者如何利用Selenium WebDriver+TestNG+ReportNG来实现web自动化。注:该Scenario会贯穿整个文章。框架
Sample Scenario:dom
简要描述: 在Jazz.net上提问模块化
步骤:1.打开Jazz.net: https://jazz.net/
2.点击Log in链接
3.以某用户名登陆
4.输入密码
5.点击Log In button
6.验证Profile Image是否出现
7.点击Forum链接
8.点击Ask a question按钮
9.在提问页面填写全部必填域,提交问题
10. 验证问题是否提交成功
11. Log out
1. 为了快速产生一个自动化脚本,咱们能够利用Selenium IDE来录制原始的脚本,而后根据须要把脚本Refine成为易于维护的版本(固然,若是你对Selenium的web driver的API很熟悉,而且有一个很好的测试框架能够采纳,也能够直接写脚本)。Selenium IDE是一个Firefox add-on,易于安装和使用,这里不作介绍,只附一张经过Selenium IDE录制上面的sample scenario的截图,图1:
录制完成以后,将其导出成Java/JUnit4/WebDriver格式(图2),而且命名为PostAQuestionInJazzDotNet。
2. 在Eclipse IDE中创建一个Java project,创建以下的文件夹结构,图3
将刚导出的PostAQuestionInJazzDotNet.java放入cases文件夹,data文件夹用来存储脚本中须要用到的数据,map 文件夹中用来存储脚本中用到的对象的属性信息,lib文件夹中用来放置所须要的依赖jar包。目前须要将selenium web driver相关的jar包放入到lib中,而且加入到build path中。
打开PostAQuestionInJazzDotNet.java,修复编译错误,例如将包名修改成cases,如图4:
▲图4 经过Selenium IDE导出的JUnit格式的java脚本
修复编译错误后的脚本应该已经能够运行,但基于如下缘由,咱们须要对脚本重构:
a. 录制出来的脚本易读性通常。
b. 数据/对象属性与测试逻辑混为一体,不便于维护。
c. 导出的脚本是基于JUnit的,咱们须要修改成TestNG的。
3. 重构脚本
3.1 将测试数据从测试逻辑中分离,也即参数化数据。
咱们采用csv做为存储数据的格式,如图5所示:(截图为经过Excel打开的显示的样式)
▲图5 以CSV格式来存储数据
第一行为每一个数据项指定一个逻辑的名字,以逗号分隔,从第二行起,在对应的数据列中填上脚本中要用到的数据值,支持多行数据的存储,便于之后实现数据驱动。
建立DataHelper类,用于从数据文件中获取数据。
其中包含的主要方法有:
initFullAppData,用于将数据读入内存,代码片断以下:
▲图6 initFullAppData代码片断
getAppData,用于根据数据项的逻辑的名字读取出某行的值,代码片断以下:
▲图7 getAppData代码片断
在脚本中能够这样使用:
在setUp方法中调用:DataHelper.initFullAppData(this, projectPath, cassName);
而后在其余测试方式中能够直接经过 DataHelper.getAppData("PostAQuestionInJazzDotNet_data:JazzURL",1);得到数据值, 其中第一个参数是数据项的全名,第二个参数是该数据项的第几个值(这点是为了考虑作iteration,也即数据驱动测试所设置的)
3.2 将web上的元素的属性值从测试逻辑中分离
这里须要了解一下Selenium如何查找定位web元素。
By.id
By.cssSelector
By.linkText
By.name
By.xpath
By.partialLinkText
经过以上的locator能够看出来Selenium支持利用多种属性定位,那咱们须要将对象的属性存储在独立的文件中,便于维护和重用,所以咱们以以下的xml的格式来存储元素的属性值,以下图:
▲图8 用XML格式来存储对象属性
其中,例如 LoginLink为对象的逻辑名称,能够由测试人员本身定义;propertyName来指定用何种方式来定位元素,可选的值包括:id, name, link, dom, xpath, css, partiallink;value用来存储属性值。
建立AutoObjectFactory类来管理对象属性文件,代码片断以下:
▲图9 AutoObjectFactory代码片断
在脚本中能够这样使用:
在case中定义:private AutoObjectFactory factory = AutoObjectFactory.createInstance(
"PostAQuestionInJazzDotNet_map.xml", projectPath
+ File.separator + "map");
而后在测试方法中经过:WebElement element = factory.getWebElement("PostAQuestionInJazzDotNet_map:userName", driver, defaultTimeOut);得到对象,而后调用相应的方法对其进行操做,例如:
element.sendKeys(DataHelper.getAppData("PostAQuestionInJazzDotNet_data:userName",1));
经过两步分离以后,脚本结构更加清晰,以下图所示:
▲图10 两步分离以后的脚本的代码片断
看似测试数据与测试逻辑的分离,对象属性与测试逻辑的分离,有些额外的efforts要作,但从长远来讲对于脚本的重用,维护都有不少益处,例如:对象 和数据能够在多个脚本之间公用,若是对象或者数据有变化,只须要在其独立文件中修改,修改后的内容天然得以在引用它的多个脚本中生效。
结合TestNG让自动化测试的流程掌控自如
尽管目前的脚本结构已经很清晰,数据和测试逻辑也都分离开来,易于维护,但从测试调度的角度以及可重用的角度来看,还须要进一步改进。
TestNG,即Testing Next Generation,下一代测试技术,是一套根据JUnit 和 NUnit思想而构建的利用注释来强化测试功能的一个测试框架,既能够用来作单元测试,也能够用来作集成测试。
一般编写一个测试的过程有三个典型步骤:
* 编写测试的业务逻辑并在代码中插入TestNG annotation
* 将测试信息添加到testng.xml文件或者build.xml中
* 运行TestNG
在上述段落中咱们的Sample scenario是一个相对长的测试用例,若是是将此用于手动测试,应该不失为一个好的测试用例,可是用在自动化测试中,咱们指望能够尽量模块化咱们的 脚本,以便于之后重用。模块化以后,咱们就能够利用TestNG的Annotation指定该模块什么时候运行,以及运行顺序等,在多个测试用例中也能够重 用。
从新组织的Sample Scenario以下:
1.打开Jazz.net: https://jazz.net/
2.打开Login页面
3.输入有效的登陆数据
4.进入提问页面
5.填写提问内容
6.提交提问
7.验证提交是否成功
8.Logout
在重构脚本且给测试方法添加TestNG的Annotation以前,须要将Junit的Annotation去除掉,而后引入TestNG相关的Jar包:testng-6.*.jar,添加TestNG的Annotation。通过重构后,脚本片断以下:
▲图11 添加TestNG的Annotation
利用TestNG的优点,咱们能够把一些初始化/ 收尾工做的测试方法用@BeforeSuite/@AfterSuite,@BeforeGroups/@AfterGroups, @BeforeTest/@AfterTest等标记, 也能够用一些属性控制它是否无论什么状况下都执行,定义其依赖的方法等。
例如:
▲图12 @BeforeSuite的用法
▲图13 @AfterSuite以及属性alwaysRun的使用
为了定义测试的执行顺序,须要创建xml文件,定义执行顺序。具体的XML中各个节点和属性的含义请参阅TestNG官方站点。
▲图14 用于定义执行顺序的XML文件
而后在main方法经过TestNG来读取xml文件以驱动测试的执行,代码片断以下:
▲图15 经过程序调用TestNG
运行测试用例以后,产生的TestNG的report以下:
咱们在充分了解了TestNG的各类Annotation以及如何控制其执行行为,就能够把模块化的测试方法调度的更好,也能够作到很好的重用。
利用ReportNG生成美观易读的测试报告
从上个章节中,咱们能够看到TestNG有其默认的report,尽管其内容较全面,但不易阅读,所以咱们想利用ReportNG来替代TestNG默认的report。
ReportNG提供了简单的方式来查看测试结果,并能对结果进行着色,还能够经过修改模板定制化内容,修改CSS来替换默认的输出样式等。
为了使用ReportNG,首先咱们要引入reportng-1.1.4.jar和velocity-dep-1.4.jar,或者直接导入有其源代码,进行定制化。
举例说明咱们进行的一些定制化的内容:
1. 默认的ReportNG的报告中,是以字母序对执行的方法进行排序的,这不是咱们指望的,咱们指望是以方法的执行前后顺序来进行排序的,故修改了TestResultComparator类,以下图:
▲图17 TestResultComparator代码片断
2. 但愿报告中显示的信息更加详细,且有截图,故定制化了模板文件/本地化文件等,如图:
▲图18 本地化Properties文件
▲图19 报告输出模板文件
3. 在ReportNGUtils中添加截图的相关方法,以下图所示:
▲图20 截图的相关代码片断
4. 在main方法中修改代码,使得testNG使用定制化后的report做为报告输出。
▲图21 修改Main方法
再次运行该测试用例,获得的测试报告以下:
Overview
▲图22 报告的整体预览
Details
▲图23 报告的详细测试结果
截图能够放大/全屏观看,以下图:
结束语
一套成熟的自动化框架是须要在项目实践中持续优化的,只有不断的实践才能发现问题,解决问题,积累经验,逐步完善。但愿做者提供的这一实践能够给读者一 些借鉴,但这一实践还远远未达到完善的地步,咱们愿意和你们一块儿多思考,多交流,结合本身的项目特性灵活运用,合理改进已达到能真正运用工具解放平常繁琐 劳动,提升效率,保证质量的效果。
做者简介
皇甫鹏: IBM CDL高级软件工程师, QA lead,从事自动化测试工具的设计和开发,以及创新工具的开发等。在Developworks和其余期刊上发表过多篇文章。
陈宇:IBM GDC 软件测试工程师,主要从事功能测试,自动化测试
余新龙: IBM GDC高级软件测试工程师,主要从事Web自动化测试。