Web自动化测试介绍

说到Web网页自动化测试,最流行的标准就是基于WebDriver/Selenium的实现,已经被W3C定义为浏览器标准。

说明: WebDriver 等同于Selenium2

Selenium/WebDriver 介绍

WebDriver 是一个跨浏览器的网站自动化测试API,主要包含以下几方面

  • 浏览器控制: 导航, 截屏, 窗口控制
  • 用户输入模拟: 鼠标, 键盘, 文件上传, 警告处理
  • Web相关: 查找/查询页面元素, 执行JavaScript, 操作cookies

Grid

使用Grid的好处是:

  • 可以运行多浏览器测试: 可组合不同的操作系统个浏览器及版本
  • 加速测试执行: 可以在多台机器并行的运行测试.

主要有两部分组成:

  • hub: 中心的入口,负责把JSON格式的测试命令路由到已注册的节点
  • node: 具体执行测试的远程实例

其他命令行选项:

  • -debug: 打印debug日志到控制台
  • -log log.txt: 记录日志到文件
  • 默认绑定0.0.0.0,可通过 -host 指定IP地址

Hub

运行hub:

# start the hub, 默认端口4444, 通过参数 -port 修改
java -jar selenium-server-standalone-3.141.59.jar -role hub
# 使用配置文件
-hubConfig hubConfig.json

可通过 http://localhost:4444/grid/console 查看状态

Node

运行node:

# start the node
java -jar selenium-server-standalone-3.141.59.jar -role node -hub http://localhost:4444/grid/register
# 其他
java -Dwebdriver.chrome.driver=/path/to/chromedriver -jar selenium-server-standalone-3.141.59.jar 
# 使用配置文件
-nodeConfig node1Config.json
# Chrome Only
chromedriver --port=4444 --url-base=wd/hub

Remote Client/Server

客户端配置:

# 客户端连接时使用RemoteDriver,command_executor值设置为 hub 地址
http://localhost:4444/wd/hub

注: 只有在执行Remote Driver(Grid)时,才需要搭建Selenium Server

一些辅助工具和框架

# 启动 Zalenium,增加额外参数
docker run --rm -ti --name zalenium -p 4444:4444 \
      -v /var/run/docker.sock:/var/run/docker.sock \
      -v /tmp/videos:/home/seluser/videos \
      --privileged dosel/zalenium start  --desiredContainers 1 --timeZone "Asia/Chongqing" --retentionPeriod 15

# 停止 Zalenium
docker stop zalenium
# 设置视频名称
test_name = os.getenv("BUILD_TAG")
if test_name:
    capabilities['name']= test_name

# 增加测试用例名称
driver.add_cookie({"name": "zaleniumMessage", "value":"my first test"})

如何定位元素

找到唯一定位元素的方式.

选择顺序:

  • 优先选择有id或唯一name属性的方式
  • link text
  • 属性组合能唯一定位的采用CSS属性选择器
  • 文档结构能唯一定位的可采用CSS结构伪类选择器
  • 相关元素可以精确定位的可借助关系选择器

CSS Selector 元素定位

简单选择器

  • ID选择器: #id
  • 类选择器: .class
    • div.value等价于div[class~=value]
    • p.pastoral.marine{color:green} 匹配class属性即包含pastoral又包含marine且两者用空格分隔的p标签
  • 类型/标签选择器: 具有相同类型的元素
  • 通配符选择器: * 后面可以跟伪元素,比如div *:first-child
  • 属性选择器: 对元素属性进行匹配
    • 存在和值选择器
      • [att] 具有att属性的元素
      • [att=val]
      • [att~=val] 与空格分隔的多个值的其一匹配
      • [att|=val] 值为val或以val-为前缀
    • 子串匹配属性选择器
      • [att^=value] 属性值前缀为val
      • $ 后缀, *含有
  • 伪类选择器: 以冒号开头,子节点位置索引从1开始
    • 结构伪类: :root , :nth-child() , tag:nth-of-type() , :nth-last-child() , :nth-last-type()
    • 内含伪类: :contains()

关系选择器:

空格 ,大于号>, 加号+, 波浪号~

  • 后代选择器: 使用空格分隔两个简单选择器
  • 子选择器: 使用大于号分隔以代表父子关系
  • 兄弟选择器: 相邻用加号分隔, 一般兄弟用波浪号分隔

组合选择器

由多个简单选择器用逗号拼接而成,满足任意其中之一选择器的元素会被选中

XPath

//input[@name=‘username’]

辅助工具

Chrome扩展:

  • CSS Selector Helper for Chrome
  • POM Builder
  • Selenium Page Object Generator

实践指南

  • 使用页面对象模型
  • 将每个测试编写为独立单元(不依赖其他测试)
  • 避免共享测试数据
  • 每次测试都刷新浏览器/启动一个新的WebDriver
  • 可使用API登录并设置Cookie的方式获取访问权限
  • 尽可能保持定位器的紧凑性和可读性: 遍历 DOM 结构的性能花销很大,搜索范围越小越好

页面对象模型

页面对象模型是自动化测试中一种易于维护和减少代码的设计模式,PO对象作为一个与页面交互的接口. 测试中需要与页面的UI进行交互时, 便调用PO的方法.

PO设计模式的优点是:

  • 测试代码和页面定位代码相分离
  • 页面提供的方法/操作或元素在独立的类,而不是分散在整个测试中

他的思想是应该暴露你要交互的服务而不是具体实现,即你的测试方法不应该包含最底层的WebDriver API。

如果某些复杂UI的层次结构只是用来组织UI,应该与page对象分离开。判断或断言是测试的一部分,应该与页面对象分离。

PO不一定需要代表整个页面. PO设计模式可用于表示页面上的组件.

Martin Flower最早提出的Page Object英文版/中文版

页面工厂

使用页面工厂实例化页面对象的设计模式. (TODO)

Selenium内置PageFactory.

反模式

  • 规避验证码
    • 在测试环境禁用验证码
    • 添加钩子以允许测试绕过
  • 文件下载: 应该使用Selenium查找下载链接,并交给HTTP请求库处理
  • 页面错误检查: 可通过页面加载后检查标题或h1标签等形式判断是否错误页面
  • 避免登录第三方站点: 通常的经验是, 执行时间较长的测试会更加脆弱和不可靠.
  • 测试应该能够以任何顺序运行,而不依赖其他测试

常见术语

  • XHR/ XMLHttpRequest : 用于在不刷新页面的情况下请求特定URL并获取数据。如果用于从服务端接受事件或消息数据,可考虑使用EventSource或全双工的WebSocket

扩展阅读