0.问题

今天看到公司的同事们在讨论page object的相关知识(也就是面向Web项目的自动化测试中的一种实现形式),刚好前一阵子研究了一下我们项目组使用的page object相关内容,所以在这里写篇入门级别的文章,跟大家介绍一下gizmo这个小工具。

(大家可以先通过这篇文章看看page object的概念 http://www.infoq.com/cn/articles/domain-web-testing)

说起来我研究gizmo也是有一段故事的,那天在工作时突然发现项目中一段代码是这样的

on_page_with(:mega_menu) do |mega_menu|    mega_menu.should have_single_word_space_caption(spaces.hashes)end

其中调用了 have_single_word_space_caption这个方法,但是我却发现方法是这样定义的

def has_single_word_space_caption? spaces   ...end

这不是很奇怪么,定义的时候明明是'has',调用时候却使用'have'...,于是我又找了找,发现了更奇怪的方法调用

on_page_with(:mega_menu) do |mega_menu|  mega_menu.should have_space_title(space_name)end

def has_space_title? space_nameend

这个更离谱,have变has不说,连方法名最后的问号都没有了。自己想了半天都没想通,又问了问别人,也没有得到让我满意的答案,哎,没办法,只能踏上寻宝之路了。这段代码是我们利用gizmo,一个Ruby gem,来完成的page object模型,也就是说我们利用gizmo对我们项目中出现的网页都建立了模型,并且给这些网页模型中加入了相关方法。想找到为什么have变has,那么就先来google gizmo吧。(我会默认你接触cucumber测试,rspec,capybara等,就算你没有,我想理解下面的问题也不会很难的。)

1.gizmo简介

gizmo(https://github.com/icaruswings/gizmo)一个page object testing framework,秉承ruby中那种简单随意的风格,利用它,你很快就可以建立起一套合适的page object来。

2.gizmo module

首先介绍的就是gizmo module ,gizmo认为一个module就是在网页上面能独立出现的一块元素,比如淘宝最上方永远都出现的登陆窗口,或者是最下面的联系我们等。我个人认为,一个页面总是可以分解成不同的module。

简单来说,gizmo的module需要满足以下条件:

  • module名字必须以PageWith开头,如下面的PageWithGithubSearch,module的文件名必须是page_with开头,如page_with_github_search.rb
  • 必须 include Gizmo::PageMixin
# I'm gizmo modulemodule PageWithGithubSearch  include Gizmo::PageMixinend

 

  对于一个module来说,我个人建议最好不要将module当成是一个页面。因为某些网页中可能存在相同的块,比如我上面提到的淘宝的例子,如果我们将相同的内容抽成module,就像抽取方法一样,项目中就不会有重复的代码啦~~

3.gizmo method

有了module,我们该定义怎样的方法来满足我们的使用呢?总体来说,我们一般会用到四类方法

  • 判断页面是否加载正常
  • 与网页有所交互,比如点击按钮,输入文字等
  • 判断页面某元素是否存在或者不存在
  • 读取网页上面的信息
module PageWithGithubSearch

  include Gizmo::PageMixin

  def valid?    has_selector?("form[action='/search']")  end

  def link_with_text(value)    find("a", :text => value)  end

  def have_content(value)    has_content?(value)  end

  define_action :click_element do |element|    locate(element).click  endend

  

  上述代码中,valid?方法就是判断页面是否加载正确(准确的说是页面中的某一个独立的块是否加载正确),你可以直接使用capybara的方法来帮助你判断加载是否成功(capybara, https://github.com/jnicklas/capybara)。如果某些情况你不需要验证是否加载正确,那么就不需要valid?方法,gizmo默认的valid?方法会永远返回true。

  define_action能帮助我们定义与页面上进行交互的方法,后面的:click_element是方法名,block中的参数是方法的参数。实现依然是capybara的代码,虽然在定义时我们使用了define_action(gizmo自已的dsl),但实际上运行时它还是会定义一个方法,之所以引入define_action的概念,个人觉得是可以非常方便的区分每个方法的职责,如果你需要与界面交互的方法,那就用define_action吧。

  link_with_text方法帮我们读取页面中的text值是value的a标签并且返回该标签,实际上find方法还是capybara的方法。

  have_content方法能判断该页面中是否包含某段文字。

  通过上面的介绍,我们就可以用valid?,define_action,def 这三种形式完成对module行为的定义。而在实现时,使用capybara来完成具体的操作(上述例子比较粗糙,希望大家在实际中能更多的参考capybara文档)。有人问我能否全部用def,不用define_action来定义方法,我觉得从功能来说完全可以,但是既然使用gizmo,那么就老老实实遵守规定吧。

4.gizom call

总算定义完module了,那么我们该怎么用呢?其实很简单,直接上代码:

on_page_with :github_search do |page|  page.perform :search, queryend

on_page_with :github_search do |page|  page.should have_content("github")end

所有使用gizmo的时候都需要on_page_with方法,第一个例子中后面传入的:github_search是module的名字,注意需要去掉前面的PageWith并且全部小写,单词之间需要下划线,还要在前面加上冒号,比如PageWithGithubSearch就是:github_search。后面是你需要操作的block,如果我们需要调用define_action定义的方法,需要使用perform方法,然后传入的:search是方法名,后面跟方法的参数query.

在第二个例子中,我们使用rspec中的should来判断 have_content("github")的返回值,也就是判断页面上是否包含github字符串。(不知你发现了没有,我定义的时候是方法名是has开头,调用时使用have并且去掉了'?')

简单来说,on_page_with后面跟的就是使用module的名字,如果我们需要操作页面,就是用perform方法,如果需要进行某些判断,则使用rspec来完成。

5.configuration

对于使用者来说,最麻烦的就是配置问题了。我在gizmo主页上也没有找到很详细的配置文档,所以就给大家分享一下我的配置内容吧。

#features/support/env.rbrequire 'capybara' require 'capybara/dsl' require 'capybara/cucumber'require 'gizmo'

Capybara.default_driver = :seleniumCapybara.default_wait_time = 10Capybara.default_selector= :cssCapybara::Selenium::Driver::DEFAULT_OPTIONS[:resynchronize] = falseCapybara.ignore_hidden_elements = false

World(Capybara) World(Gizmo::Helpers)

Gizmo.configure do |config|  config.mixin_dir = File.dirname(__FILE__) + '../page_object'end

值得说明的最后一部分,设置Gizmo.configure中设置的是存放gizmo module的文件夹,他是相对于env的路径,也就是说我可以把放gizmo module的文件夹叫做pages,并且把相关的module放在一个子文件夹下面进行管理。比如下面这种组织形式

page_object/├── home_page│   ├── page_with_login.rb│   └── page_with_search.rb└── setting_page├── page_with_password.rb└── page_with_photo.rb

最后,你需要参照 https://github.com/icaruswings/gizmo/wiki/Capybara,给你的capybara打上补丁才能工作。

那么,如果你有什么问题,可以给我留言,不过我建议你最好仔细看一看gizmo主页上面的介绍。那么,还等什么,开始page object之旅吧。

ps:到现在为止,我依然没有确定have和has这个问题的答案,如果你知道,请你告诉我,谢谢。  

转载于:https://www.cnblogs.com/iammatthew/archive/2012/02/22/2359298.html

Web自动化测试模式page object的小利器:gizmo相关推荐

  1. Python+Selenium自动化测试:Page Object模式

    Page Objects是selenium的一种测试设计模式,主要将每个页面看作是一个class.class的内容主要包括属性和方法,属性不难理解,就是这个页面中的元素对象,比如输入用户名的输入框,输 ...

  2. java page object_Selenium+java - Page Object设计模式

    前言 Page Object(页面对象)模式,是Selenium实战中最为流行,并且被自动化测试同学所熟悉和推崇的一种设计模式之一.在设计测试时,把页面元素定位和元素操作方法按照页面抽象出来,分离成一 ...

  3. Selenium的PO模式(Page Object Model)|(Selenium Webdriver For Python)

    Selenium的PO模式(Page Object Model)|(Selenium Webdriver For Python) 研究Selenium + python 自动化测试有近两个月了,不能说 ...

  4. 微信小程序教程02:App(Object)和Page(Object) 构造器介绍

    在/app.js中,有方法App,它的作用是注册整个小程序的应用,其中可以传入一些配置,或者存储全局状态. App(Object) 构造器生命周期 属性 类型 描述 onLaunch Function ...

  5. python selenium po_python+selenium基于po模式的web自动化测试框架

    一.什么是Selenium? Selenium是一个基于浏览器的自动化测试工具,它提供了一种跨平台.跨浏览器的端到端的web自动化解决方案.Selenium主要包括三部分:Selenium IDE.S ...

  6. java web典型模块大全_python+selenium基于po模式的web自动化测试框架

    一.什么是Selenium? Selenium是一个基于浏览器的自动化测试工具,它提供了一种跨平台.跨浏览器的端到端的web自动化解决方案.Selenium主要包括三部分:Selenium IDE.S ...

  7. ide循环执行用例 selenium_Selenium Web自动化Page Object设计模式——循环执行测试用例...

    继续优化上一篇博客的设计 Selenium Web自动化Page Object设计模式--driver初始化 https://www.cnblogs.com/Ravenna/p/14172411.ht ...

  8. python+selenium基于po模式的web自动化测试框架

    目录:导读 一.什么是Selenium? 二.自动化测试框架 三.自动化框架的设计和实现 四.需要改进的模块 五.总结 一.什么是Selenium? Selenium是一个基于浏览器的自动化测试工具, ...

  9. Web自动化测试02

    Web自动化测试课程 第2章-Selenium-API操作 元素定位 元素定位-XPath.CSS 元素操作|浏览器操作方法 鼠标和键盘操作 元素等待 下拉选择框.弹出框.滚动条操作 frame切换. ...

最新文章

  1. [Android]生成heap dump文件(.hprof)
  2. Visio 快捷大全(转载)
  3. 深度解读.NET 5授权中间件的执行策略
  4. java enum in class_Java 8需要一个转换,而Java 7没有 – enum.getClass/getDeclaringClass
  5. 使用Sublime Text 3做Python开发
  6. 推荐一款接口 API 设计神器!
  7. 8月份的To-Do List
  8. 从git repo分支安装pip
  9. 也玩ASP.NET MVC 与 WebFroms 整合
  10. 惠普m1216硒鼓清零步骤_惠普m1136打印机怎么清零
  11. 【sketchup 2021】草图大师中CAD文件的导入与建模(利用cad图纸在草图大师中建立立面模型)、草图大师导出成品为dwg格式的二维、三维、立面效果到cad中打开预览】
  12. 北京公司买车,都需要什么手续?摇号有什么特殊要求?
  13. steam使用技巧2
  14. FREEIPA:ipa-server的部署使用
  15. Chromium Embedded Framework (CEF) 介绍
  16. DEFCON 23|专门抓捕黑客的人
  17. 正态分布与泊松分布的关系
  18. Windows远程桌面连接报错【无法连接到远程计算机】
  19. 不是每个音乐节都值得狂欢,抖音就不一样
  20. 【游戏推荐】癞子斗地主--OGEngine精品游戏推荐系列【一】

热门文章

  1. 手机当作电脑无线摄像头
  2. ps在html中的应用程序,Photoshop在网页设计中的应用
  3. Win11 与 macOS 12 界面对比
  4. 第 1 章 程序设计基本方法
  5. 网络硬盘(简称网盘)
  6. [导入]转帖------牛逼顿
  7. Echarts地图使用扩展(1)
  8. 关于图片onload事件兼容性处理, 谷歌浏览器版本 56.0.2896.3 (64-bit) 微信客户端浏览器 canvas篇
  9. 【网络原理】知识点汇总2
  10. C/C++语言100题练习计划 97——素数对