自动化测试之Selenium
Selenium 是用于 web 应用的自动化测试工具,可以模拟浏览器操作,自动完成 web 基本任务管理。
自动化测试
适合自动化测试的情况:
- 项目周期长且相对稳定
- 需要做频繁的冒烟测试
- 需要经常做回归测试
- 需要进行大数据量的数据驱动测试
不适合自动化测试的情况:
- 项目周期短,且用例不会多次重复执行
- 被测项目不稳定,变化频繁
需要关注的指标:
- 自动化测试用例的覆盖率
- 节省的时间成本 = 手工测试所花时间 - 自动化测试所花时间
- 自动化测试的投入
- 自动化测试发现的缺陷数
- 关键指标是: 自动化测试的投入产出比 ROI = (手工测试的成本 - 自动化测试的成本) / 自动化测试的成本,ROI 为正值且越大说明回报越好
Selenium 原理
selenium 的原理涉及到三个部分:
- WebDriver API,即 client,也就是写的代码
- 浏览器驱动 driver,也就是下载的 chromedriver.exe
- 浏览器
Selenium 执行流程
client 并不知道浏览器是如何工作的,可以通过 driver,实现 client 与浏览器之间的通信,client 根据 webdriver 协议发送请求给 driver,driver 解析请求,并在浏览器上执行相应的操作,并把执行结果返回给 client。具体如下:
- 对于每一条 Selenium 脚本,一个 HTTP 请求会被创建并且发送给浏览器的驱动
- 浏览器驱动中包含了一个 HTTP Server,用来接收这些 HTTP 请求
- HTTP Server 接收到请求后根据请求来具体操控对应的浏览器
- 浏览器执行具体的测试步骤
- 浏览器将步骤执行结果返回给 HTTP Server
- HTTP Server 又将结果返回给 Selenium 的脚本,如果是错误的 HTTP 代码,控制台会显示相应的报错信息。
webdriver 协议
webdriver 基于的协议是 JSON Wire protocol,数据传输使用的是 json,JSON Wire protocol 是在 http 协议基础上,对 http 请求及响应的 body 部分的数据进一步规范。
在 client 和 server 之间,只要是基于 JSON Wire Protocol 来传递数据,无论 client 使用 java、python 还是其他语言实现,driver 都能处理相应的脚本。
Selenium 的简单使用
1 | from selenium import webdriver |
- driver.quit(): 退出并关闭窗口的每一个相关的驱动程序
- driver.close(): 关闭当前窗口
Python webdriver API
元素定位
webdriver 提供了一系列的对象定位方法,常用的有:
- find_element_by_id(),唯一
- find_element_by_name(),唯一
- find_element_by_class_name()
- find_element_by_linx_text(), 操作对象是文字超链接
- find_element_by_partial_link_text(),操作对象是文字超链接
- find_element_by_tag_name(), 标签名
- find_element_by_xpath()
- find_element_by_css_selector()
定位一组对象,用 find_elements,返回的是一个 list,可以用于批量操作对象,如选择复选框
- find_elements_by_tag_name()
- find_element_by_css_selector()
判断元素是否存在: 需要用元素定位和异常捕获的方法判断
1 | try: |
注意: 在 selenium 中不能定位不可见元素,比如 hidden 和 display=none 的元素
操作测试对象
- clear() :清除内容
- click() :鼠标点击
- send_keys() :向输入框输入
- submit() :提交表单
显式等待和隐式等待
显示等待 WebDriverWait():是针对某个特定元素设置的等待时间,在设置时间内,默认每隔一段时间检测一次当前页面某个元素是否存在,如果在规定的时间内找到了元素,则直接执行,即找到元素就执行相关操作,如果超过设置时间检测不到则抛出异常。
隐式等待 implicitly_wait():是设置了全局等待,设置等待时间,是对页面中的所有元素设置加载时间,如果超出了设置时间的则抛出异常。隐式等待可以理解成在规定的时间范围内,浏览器在不停的刷新页面,直到找到相关元素或者时间结束。
强制等待 sleep():也叫线程等待,设置固定休眠时间,执行 sleep() 后线程休眠,上面两种等待不会休眠。
Appium
appium 是一个自动化测试开源工具,支持 iOS 平台和 Android 平台上的原生应用,web应用和混合应用。
- 移动原生应用 native:用 iOS 或 Android SDK 写的应用
- 移动 web 应用 H5:使用移动浏览器访问的应用
- 混合应用:原生代码封装网页视图,原生代码和 web 内容交互
appium 类库封装了标准 Selenium 客户端类库,实现了 Mobile JSON Wire Protocol
流程: 使用 python(client)编写一个 appium 自动化脚本并执行,首先会请求 appium-Server(mac 和 win 下不同),appium-Server 通过解析,驱动 Android 虚拟机或真机来执行 appium 脚本。
元素定位
可以使用 uiautomatorviewer 工具来查看控件的属性,定位方式与 selenium 相同,有 id、name、class_name、xpath 等方法。
native 与 h5 切换
在混合开发的 app 中,原生应用可以通过 uiautomator 获取控件信息,而 h5 也就是 web 网页是 B/S 架构,两者的运行环境不同,因此需要进行上下文(context) 切换,再对 h5 页面元素进行定位操作。
切换到 h5,进行 h5 元素定位:
- 导航到应用程序中 web 页面
- 获取上下文列表 driver.contexts,它返回一个我们可以访问的上下文列表,例如:NATIVE_APP 或 WEBVIEW_xxx
- 通过 driver.switch_to.context 切换到你要操作的 webview,原来是在 NATIVE_APP,切换到 WEBVIEW_xxx
- 操作完后,返回到原来的 app view
断言
断言是一些布尔表达式,当需要在一个值为 False 时中断当前操作的话,可以使用断言。
断言可以用于单元测试,判断到某个节点位置必须满足某些逻辑条件时才能继续运行下去,不满足程序就会崩溃或报错,这个时候就可以使用断言。
断言与异常
- 断言用于开发测试期间,是给程序员自己使用的;断言触发后程序崩溃退出,不需要从错误中恢复
- 异常在程序运行期间触发;异常通常会用 try/except/finally 等结构捕获异常,之后还能从错误中恢复继续运行
python 常用断言
- assertEqual(a, b [, msg=’xxx’]): 断言 a 和 b 相等,msg 为测试失败时打印的信息; assertNotEqual(a, b)
- assertIs(a, b [, msg=’xxx’]): 断言 a 是 b; assertNotIs(a, b)
- assertIn(a, b [, msg=’xxx’]):断言 a 在 b 中; assertNotIn(a, b)
- assertIsInstance(a, b [, msg=’xxx’]): 断言 a 是 b 的一个实例; assertNotIsInstance(a, b)
- assertTrue(x [, msg=’xxx’]): 断言 x 为 True; assertFalse(x)
- assertIsNone(x [, msg=’xxx’]): 断言 x 是 None; assertIsNotNone(x)