51Testing软件测试论坛

标题: 应用Selenium和Ruby进行面向领域的Web测试[1] [打印本页]

作者: 8002tacylf    时间: 2008-8-14 10:33
标题: 应用Selenium和Ruby进行面向领域的Web测试[1]
应用Selenium进行Web测试时,经常会遇到下面的几个麻烦问题:
   大量使用name、id、xpath等页面元素。无论是功能修改、UI重构还是交互性改进都会影响到这些元

素,这使得Selenium测试变得非常脆弱。
   过于细节的页面操作不容易体现出行为的意图,一段时间之后就很难真正把握测试原有的目的了,这

使得Selenium测试变得难于维护

   对具体数据取值的存在依赖,当个别数据不再合法的时候,测试就会失败,但这样的失败并不能标识

功能的缺失,这使得Selenium测试变得脆弱且难以维护。
   而这几点直接衍生的结果就是不断地添加新的测试,而极少地去重构、利用原有测试。其实这倒也是

正常,单元测试测试写多了,中国IT室验实也有会有这

样的问题。不过比较要命的是,Selenium的执行速度比较慢(相对单元测试),随着测试逐渐的增多,

运行时间会逐渐增加到不可忍受的程度。一组意图不明而且难以维护的Selenium测试,可以很轻松地在

每次构建(Build)的时候杀掉40分钟甚至2个小时的时间,我就有曾有花2个小时坐在电脑前面等待450

个 Selenium测试运行通过的悲惨经历。因此合理有效地规划Selenium测试就显得格外的迫切和重要了。

而目前比较行之有效的办法,往大了说,可以叫基于领域的Web测试(Domain Based Web Testing),具

体来讲,就是Page Object Pattern。
   Page Object Pattern里有四个基本概念:Driver、Page、Navigator和Shortcut等。Driver是测试真

正的实现机制,比如 Selenium,比如Watir,比如HttpUnit。它们懂得如何去真正执行一个Web行为,通

常包含像Click、Select、Type等这样的表示具体行为的方法;Page是对一个具体页面的封装,它们了解

页面的结构,知道诸如id、name、class和xpath这类实现细节,并描述用户可以在其上进行何种操作;

Navigator则代表了URL,表示一些不经页面操作的直接跳转;最后Shortcut就是helper方法了,需要看

具体的需要而定。下面来看一个超级简单的例子——测试登录页面。
   1. Page Object
   假设我们使用一个单独的登录页面进行登录,那么可能会将登录的操作封装在一个名为LoginPage的

page object里:
   class LoginPage
       def initialize driver   
           @driver = driver
       end   
       def login_as user   
           @driver.type 'id=', user[:name]   
           @driver.type 'xpath=', user[:password]   
           @driver.click 'name='   
           @driver.wait_for_page_to_load
       end
   end
   login_as是一个具有业务含义的页面行为。在login_as方法中,page object负责通过依靠id、xpath

、name等信息完成登录操作。在测试中,我们可以这样来使用这个page object:
   page = LoginPage.new $selenium
   page.login_as :name => 'xxx', :password => 'xxx'
   不过既然用了Ruby,总要用一些ruby sugar吧,我们定义一个on方法来表达页面操作的环境:
   def on page_type, &block
       page = page_type.new $selenium
       page.instance_eval &block if block_given?
   end
   之后我们就可以使用page object的类名常量和block描述在某个特定页面上操作了:
   on LoginPage do
       login_as :name => 'xxx', :password => 'xxx'
   end
   除了行为方法之外,我们还需要在page object上定义一些获取页面信息的方法,比如获取登录页面

的欢迎词的方法:
   def welcome_message
       @driver.get_text 'xpath='
   end
   这样测试也可表达得更生动一些:
   on LoginPage do
       assert_equal 'Welcome!', welcome_message
       login_as :name => 'xxx', :password => 'xxx'
   end
   当你把所有的页面都用Page Object封装了之后,就有效地分离了测试和页面结构的耦合。在测试中

,只需使用诸如login_as和add_product_to_cart这样的业务行为,而不必依靠像id、name等这些具体且

易变的页面元素了。当这些页面元素发生变化时,只需修改相应的page object就可以了,而原有测试基

本不需要太大或太多的改动。
作者: q_gao    时间: 2010-11-12 17:45
本帖最后由 q_gao 于 2010-11-12 17:46 编辑

最近正在研究将selenium的自动化测试应用到公司的web产品中,不过研究的头都大了,
IDE中生成的脚本总是不能够成功回放,经常有抓不到窗口以及找不到element的情况,
而且回放有时成功有时失败,似乎selenium的稳定性不是很好。

也可能是刚学习的原因,掌握的还很肤浅,有好的学习方法及建议,请多指教指教。
作者: submarinemaster    时间: 2010-11-27 15:18
学习中~~~~~~~~~~~




欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2