# UI自动化测试阶段目标
- 1.掌握使用Selenium实现Web自动化测试的流程和方法,并且能够完成自动化测试脚本的编写。
- 2.掌握使用Appium实现移动自动化测试的流程和方法,并且能够完成自动化测试脚本的编写。
- 3.掌握如何通过PyTest管理用例脚本,并使用Allure生成HTML测试报告。
- 4.掌握使用PO模式来设计自动化测试代码的架构。
- 5.掌握使用数据驱动来实现自动化测试代码和测试数据的分离。
- 6.掌握使用logging来实现日志的收集。
认识UI自动化测试
UI自动化介绍
- UI:User Interface,简称UI,用户界面是系统和用户之间进行交互和信息交换的媒介
- UI 自动化测试:使用程序、脚本对系统界面体现的功能和数据信息展示等进行的测试技术
- 分类:
为什么需要UI自动化
前置条件
- 项目需要实施UI自动化测试需要满足以下前置条件:
- 项目需要回归测试
- 项目需要实现自动化的功能模块需求变更不频繁
- 项目周期要长
执行时机
自动化的优缺点
互联网项目现状:
项目实现UI自动化测试之后:
- 节省人力成本:回归测试工作由脚本代替人去执行, 较少的时间内运行更多的测试用例;
- 提高回归测试效率:脚本执行测试速度更快,自动化脚本可以重复运行
- 提高测试质量:一旦自动化脚本库完善后测试执行过程更标准和准确 , 较少人为的错误
- 构建测试数据
- 克服手工测试的局限性
- 做为项目文档辅助
UI自动化测试劣势:
- 对测试人员要求提高
- 前期投入成本大
- 对项目要求高
- 缺点:
- 自动化测试实现步骤要依赖手工实现
- UI 界面布局一类的问题,自动化测试无法解决
- 功能测试逻辑复杂的/设计第三方交互的都太适合使用自动化测试实现
自动化测试工具Selenium
学习目标
- 了解常见的自动化测试工具
- 理解Selenium特点
- 知道Selenium核心组件和其作用
自动化测试工具介绍

- web项目实施自动化:
- web : python+selenium+unittest
- app : python+appium+unitest
Selenium 特点
Selenium 的发展史

Selenium 核心组件

Selenium环境搭建
学习目标
- 能力独立搭建 Selenium 自动化测试实施环境
环境搭建步骤
环境搭建步骤
- 所需环境:
- python 解释器
- pycharm
- selenium
- 浏览器
- 浏览器驱动
- 浏览器驱动版本需要和浏览器版本一致
- 将浏览器驱动版本 chromedriver.exe 复制至 python.exe 所在目录即可(避免再次将 chromedriver.exe 添加 path 变量)

安装Selenium
安装浏览器驱动
- 1、下载浏览器驱动程序:
- 不同浏览器都有自己独立驱动程序
- 不同的版本需要下载匹配其版本的驱动程序
- 2、配置驱动文件环境变量:
- 可直接将驱动文件拷贝到 python.exe 所在的目录即可
- 驱动程序下载地址:
入门示例
- 通过程序启动浏览通过程序启动浏览器,并打开百度首页,暂停3秒,关闭浏览器器,并打开百度首页,暂停3秒,关闭浏览器
- 通过代码生成的浏览器与系统中自己使用的浏览器不是同一个,代码执行结束后会被销毁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import time from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.baidu.com/")
time.sleep(3)
driver.quit()
|
元素定位
学习目标
为什么要进行元素定位

1 2 3
| <input type="text" placeholder="手机号/邮箱" id="username" autocomplete="off"> <input type="password" placeholder="密码" id="username" autocomplete="off"> <input type="text" placeholder="验证码" id="username" autocomplete="off">
|
- UI 界面本质上就是HTML直接体现,脚本通过HTML标签信息来找到具体的元素
查看标签信息

元素定位

1
| from selenium.webdriver.common.by import By
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
inputTag = driver.find_element(By.ID, "value")
inputTag = driver.find_element(By.CLASS_NAME, "value")
inputTag = driver.find_element(By.NAME, "value")
inputTag = driver.find_element(By.TAG_NAME, "value")
inputTag = driver.find_element(By.XPATH, "value")
inputTag = driver.find_element(By.CSS_SELECTOR, "value")
from selenium.webdriver.common.by import By
• find_element(By.ID,”loginName”) • find_element(By.NAME,”SubjectName”) • find_element(By.CLASS_NAME,”u-btn-levred”) • find_element(By.TAG_NAME,”input”) • find_element(By.LINK_TEXT,”退出”) • find_element(By.PARTIAL_LINK_TEXT,”退”) • find_element(By.XPATH,”.//*[@id=’Title”]) • login_form = driver.find_element_by_xpath("//form[@id='loginForm']") • find_element(By.CSS_SELECTOR,”[type=submit]”)
|
ID定位
ID定位
- 概念:通过元素的id属性来定位元素。
- 前置:所要定位的元素必须有id属性
- 方法:
driver.find_element_by_id(id属性值)
, 旧版本的写法,会报错
driver.find_element(By.ID, "userA")
, 新版本的写法,使用方法参考案例
- 方法返回的是什么?

案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import time from selenium import webdriver from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
username = driver.find_element(By.ID, "userA") username.send_keys('admin')
password = driver.find_element(By.ID, "passwordA") password.send_keys('123456')
time.sleep(3)
driver.quit()
|
Name定位
Name定位

案例
- 需求:
- 打开注册A.html页面,完成以下操作
- 1).使用name定位,输入用户名:admin
- 2).使用name定位,输入密码:123456
- 3).3秒后关闭浏览器窗口
- 分析:
- ①.创建浏览器驱动
- ②.打开测试网址
- ③.定位元素,调用模拟操作方法
- ④.操作完毕关闭浏览器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import time from selenium import webdriver from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
username = driver.find_element(By.NAME, "userA") username.send_keys('admin')
password = driver.find_element(By.NAME, "passwordA") password.send_keys('123456')
time.sleep(3)
driver.quit()
|
class_name 定位
class_name 定位

案例
使用 CLASS_NAME 定位方式完成下面操作
需求:
- 打开注册A.html页面,完成以下操作
- 1).通过class_name定位电话号码A,并输入:18611111111
- 2).通过class_name定位电子邮箱A,并输入:123@qq.com
- 3).3秒后关闭浏览器窗口
分析:
- ①.创建浏览器驱动
- ②.打开测试网址
- ③.定位元素,调用模拟操作方法
- ④.操作完毕关闭浏览器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| # 1. 导入模块 import time from selenium import webdriver from selenium.webdriver.common.by import By
# 2. 创建浏览器驱动对象 # Firefox浏览器: # driver = webdriver.Firefox() # Chrome浏览器: driver = webdriver.Chrome()
# 3. 打开Web页面 driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
# 3.3) 通过class_name定位电话号码A,并输入:18611111111 te= driver.find_element(By.CLASS_NAME, "telA") tel.send_keys('18611111111')
# 3.4) 通过class_name定位电子邮箱A,并输入:123@qq.com mai= driver.find_element(By.CLASS_NAME, "c1") mail.send_keys("123@qq.com")
# 4. 3秒后关闭浏览器窗口 time.sleep(3)
# 5. 关闭驱动对象 driver.quit()
|
Tag_name 定位
Tag_name 定位
- 概念:通过元素的标签名来定位元素。
- 方法:
driver.find_element(By.TAG_NAME, "input")

案例
使用TAG_NAME定位方式完成下面操作
需求:
- 打开注册A.html页面,完成以下操作
- 1).使用tag_name定位用户名输入框,并输入:admin
- 2).3秒后关闭浏览器窗口
分析:
- ①.创建浏览器驱动
- ②.打开测试网址
- ③.使用标签名定位确认符合条件的元素是第几个?
- ④.操作完毕关闭浏览器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import time from selenium import webdriver from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
username = driver.find_element(By.TAG_NAME, "input") username.send_keys('admin')
time.sleep(3)
driver.quit()
|
link_text 定位
link_text 定位

案例
使用Link_Text定位方式完成下面操作
需求:
- 打开注册A.html页面,完成以下操作
- 1).使用link_text定位(访问新浪网站)超链接,并点击
- 2).3秒后关闭浏览器窗口
分析:
- ①.创建浏览器驱动
- ②.打开测试网址
- ③.获取要定位超链接文本类容,用拷贝的形式,定位元素
- ④.操作完毕关闭浏览器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| ```
### partial_link_text 定位
#### partial_link_text 定位
- 使用link_text定位图片标记的元素会有什么问题? - 代码过长 - 定位不到
- 使用局部文本来定位元素: - 方法:driver.find_element_by_partial_link_text(超链接的局部文本内容) - 局部文本:从字符串任意位置开始,一截连续字符集。

#### 案例
- 使用Partail_Link_Text定位方式完成下面操作
- 需求:
- 打开注册A.html页面,完成以下操作
- 1).使用partial_link_text定位(访问新浪网站)超链接,并点击
- 2).3秒后关闭浏览器窗口
- 分析:
- ①.创建浏览器驱动
- ②.打开测试网址
- ③.获取要定位超链接文本部分类容(能表示该元素唯一性),用拷贝的形式,定位元素
- ④.操作完毕关闭浏览器
```mysql # 1. 导入模块 import time from selenium import webdriver from selenium.webdriver.common.by import By
# 2. 创建浏览器驱动对象 # Firefox浏览器: # driver = webdriver.Firefox() # Chrome浏览器: driver = webdriver.Chrome()
# 3. 打开Web页面 driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
# 需求 : 使用partial_link_text定位(访问新浪网站)超链接,并点击 driver.find_element(By.LINK_TEXT,'访问 新浪 网站').click()
# 4. 3秒后关闭浏览器窗口 time.sleep(3)
# 5. 关闭驱动对象 driver.quit()
|
定位一组元素
定位一组元素
案例
Xpath定位
认识Xpath定位
路径定位
绝对路径 :
- 对界面依赖强,不建议使用
- 概念:从最外层元素到指定元素之间所有经过的元素层级的路径。
- 表达式写法:绝对路径以
/htm
根节点开始,使用/来分隔元素层级。
相对路径·
- 概念:从目标定位元素的任意层级的上级元素开始到目标元素所经过的层级的路径。
- 表达式写法:以
//
开始,后续每个层级都使用/
来分隔。
案例 :
使用 xpath 路径定位策略完成下面操作
需求:
- 打开注册A.html页面,完成以下操作
- 1).使用相对路径定位用户名输入框,并输入:admin
- 2).暂停2s
- 3).使用绝对路径定位密码输入框,并输入:123
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import time from selenium import webdriver from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
inputTag = driver.find_element(By.XPATH, "//*[@id='userA']") inputTag.send_keys("admin")
time.sleep(5)
driver.find_element(By.XPATH, "/html/body/form/div/fieldset/center/p[2]/input").send_keys("123")
time.sleep(5)
driver.quit()
|
属性定位
属性定位概念:
挑选哪个属性来定位呢?
- 挑选元素所特有的挑选较为常用的:id、name、class、value…
- 总之:尽量挑选能精准定位到唯一元素的属性
案例 :
- 需求:打开注册 A.htm页面。完成以下操作:
- 1). 利用元素的属性信息精准定位用户名输入框,并输入:admin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import time from selenium import webdriver from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
driver.find_element(By.XPATH, "//input[@placeholder='账号A']").send_keys("admin")
time.sleep(5)
driver.quit()
|
属性与逻辑结合
属性与逻辑结合
案例 :
- 需求:打开注册 A.htm页面。完成以下操作:
- 1). 利用属性与逻辑结合在输入框输入:admin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import time from selenium import webdriver from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
driver.find_element(By.XPATH, '//input[@name="userA" and @placeholder="账号A"]').send_keys("admin")
time.sleep(5)
driver.quit()
|
层级与属性结合
- 层级与属性结合
- 案例 :
- 需求:打开注册 A.htm页面。完成以下操作:
- 1). 利用层级与属性结合在输入框输入:admin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import time from selenium import webdriver from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
driver.find_element(By.XPATH, '//*[@id="p1"]/input').send_keys("admin")
time.sleep(5)
driver.quit()
|
- 案例 :
- 需求:打开注册 A.htm页面。完成以下操作:
- 1). 利用局部属性定位方式定位用户名输入框输入:admin
- 2). 利用文本定位的方式定位百度超链接,并点击
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ```
- 按要求完成下面的操作流程: - 1. 打开Tpshop首页; - 2. 使用Xpath 文本定位策略定位登陆超链接,并点击; - 3. 使用Xpath 属性定位策略定位用户名输入框,输入:15800000001; - 4. 使用Xpath 属性包含定位策略定位密码输入框,输入:123456; - 5. 使用Xpath 属性与逻辑结合策略定位验证码输入框,输入:8888; - 6. 使用Xpath 层级与属性结合策略定位登陆按钮,并点击; - 每步操作之后暂停2s
```python
|
CSS定位
认识CSS定位
CSS
- 概念:(Cascading Style Sheets)是一种语言,用来描述HTML元素的显示样式。
- 选择器:一种表达式,可以找到HTML中的标签元素。
CSS定位
- 概念:selenium利用选择器定位元素的定位方式。
- 方法 :
- 策略 :
- ID选择器
- 类选择器
- 说明:利用元素 class 属性来选择
- 格式:
.class属性值
- 元素选择器
- 属性选择器
- 层级选择器
- 父子关系
- 后代关系包含了父子关系,一般只需记忆后代关系即可
- 概念:据元素的父子关系来选择元素。
- 表达式写法:
element1>element2
- 后代关系
- 概念:根据元素的上级元素来选择元素(只要是目标元素上层元素即可)
- 表达式写法:
element1 element2
案例:
- 需求:打开注册 A.htm页面,完成以下操作
- 1).使用CSS定位方式中id选择器定位用户名输入框,并输入:admin
- 2).使用CSS定位方式中属性选择器定位密码输入框,并输入:123456
- 3).使用CSS定位方式中class选择器定位电话号码输入框,并输入:18600000000
- 4).使用CSS定位方式中元素选择器定位注册按钮,并点击
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import time from selenium import webdriver from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
driver.find_element(By.ID, "userA").send_keys("admin")
driver.find_element(By.XPATH, "//*[@id='passwordA']").send_keys("123456")
driver.find_element(By.CLASS_NAME, "telA").send_keys("18600000000") time.sleep(5)
driver.find_element(By.TAG_NAME, "button").click()
time.sleep(5)
driver.quit()
|
- 案例
- 需求:打开注册A.html页面。完成以下操作:
- 1).使用CSS定位方式中的层级选择器定位用户名输入框,并输入:admin
- 案例
- 需求:打开注册A.html页面。完成以下操作:
- 1). 利用局部属性定位方式定位用户名输入框输入:admin
- 案例
- 使用元素定位的另外一种写法完成下面的操作:
- 需求:打开注册A.html页面,完成以下操作
- 1).使用id定位用户名输入框,并输入:admin
- 2).使用name定位密码输入框,并输入:123456
- 3).使用class定位电话号码输入框,并输入:18600000000
- 4).使用标签名定位注册按钮,并点击
案例-刷步数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import time from selenium import webdriver from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://shuabu.org//")
driver.find_element(By.CLASS_NAME, "ant-modal-close-x").click()
username =driver.find_element(By.XPATH,"//input[@placeholder='请输入Zepp Life账号']") username.send_keys("13838383388")
password =driver.find_element(By.XPATH,"//input[@placeholder='请输入Zepp Life密码']") password.send_keys("12345678aa")
buShu =driver.find_element(By.XPATH,"//input[@placeholder='1~100000']") buShu.send_keys("33333")
driver.find_element(By.XPATH,"//button[@type='button']").click()
time.sleep(5)
driver.quit()
|
交互操作
元素操作和元素信息获取
学习目标
- 掌握元素操作Api实现模拟手工操作
- 掌握获取元素信息Api
元素常用操作方法
常用操作方法

案例
- 需求:打开注册A.html页面,完成以下操作
- 1).通过脚本执行输入用户名:admin,密码:123456,电话号码:18611111111,电子邮箱:123@qq.com
- 2).间隔3秒,修改电话号码为:18600000000
- 3).间隔3秒,点击【注册】按钮
- 4).间隔3秒,关闭浏览器
- 5).元素定位方法不限
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| ```
- 场景:执行商品搜索测试步骤后需要验证测试结果
- 获取元素大小 `element.size`
- 获取元素文本 `element.text`
- 获取元素属性值 `element.get_attribute(属性名")`

- 判断元素是否可见 `element.is_displayed()` - 判断元素是否可用 `element.is_enabled()` - 判断元素是否可见 `element.is_displayed()` - 返回的结果都是Boolean数据:True or False

### 案例
- 需求:打开注册A.html页面,完成以下操作 - 1).获取用户名输入框的大小 - 2).获取页面上第一个超链接的文本内容 - 3).获取页面上第一个超链接的地址 - 4).判断页面中的span标签是否可见 - 5).判断页面中取消按钮是否可用 - 6).判断页面中'旅游'对应的复选框是否为选中的状态
```python
|
浏览器操作
学习目标
浏览器操作
浏览器窗口大小
- 设置浏览器显示范围 :
- 窗口最大化
driver.maximize_window()
- 如果能够在打开页面时,全屏显示页面。就能尽最大可能加载更多的页面元素,提高可定位性
- 设置窗口大小
driver.set_window_size(width, height)
- 设置窗口位置
dirver.set_window_position(x, y)
1 2 3 4 5 6 7 8
| driver.maximize_window()
driver.set_window_size(1920, 1080)
driver.set_window_position(0, 0)
|
- 浏览器显示页面操作 :
- 后退操作 :
dirver.back()
- 前进操作 :
dirver.forword()
- 刷新页面 :
dirver.refresh()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import time from selenium import webdriver from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
driver.find_element(By.ID,"kw").send_keys("高德地图")
driver.find_element(By.ID,"su").click() time.sleep(2)
driver.back() time.sleep(2)
driver.forward() time.sleep(2)
driver.refresh() time.sleep(2)
time.sleep(5)
driver.quit()
|
案例
- 需求:
- 打开注册A.html页面,完成以下操作
- 1).最大化窗口
- 2).暂停3s,设置窗口宽度:500px,高度:700px
- 3).暂停3s,设置窗口位置:x=0px,y=500px
- 4).暂停3s,点击界面百度超链接
- 5).暂停3s,返回注册A页面
- 6).暂停3s,前进到百度页面
- 7).暂停3s,刷新百度页面
- 8).暂停3s,关闭浏览器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| ```
- 在测试过程出现多个窗口.只需要关闭其中一个,如何处理?
- 浏览器关闭操作 :
- 关闭当前窗口 `dirver.close() ` - 在没有实现浏览器页面切换操作前,`close()`方法关闭的是原始页面 , 关闭单个页面时使用
- 关闭浏览器 `dirver.quit()`
- 获取浏览器信息 : - 获取标题 `dirver.title` - 获取网页地址 `dirver.current_url`
- 当前窗口:创建驱动时第一个打开的窗口,对于当前窗口的元素一般都可以直接定位和操作,如果弹出新的窗口,对于新的窗口元素是不能直接进行操作,需要学习后续的窗口切换。
```python
import time from selenium import webdriver from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
driver.find_element(By.PARTIAL_LINK_TEXT,"访问").click() time.sleep(2)
print(driver.title)
print(driver.current_url)
driver.close()
driver.quit()
|
案例
- 完成下面对浏览器的操作
- 需求:
- 打开注册A.html页面,完成以下操作
- 1).最大化窗口
- 2).打印当前窗口的标题和地址
- 3).暂停3s,点击界面访问百度网站超链接
- 4).暂停3s,再次打印当前窗口的标题和地址
- 5).暂停3s,关闭当前窗口
- 6).暂停3s,关闭浏览器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| ```
- 能编写代码来实现各类型下拉框选择 - 能识别弹出框类型并能通过脚本来处理 - 能编写代码控制下拉框进行滑动

- 在页面上面经常遇到上面的交互,该如何进行处理? - 定位元素后调用点击的操作方法进行选择
- 需求:使用‘注册A.html’页面,完成对城市的下拉框的操作: - 1).选择‘广州’ - 2).暂停2秒,选择‘上海’ - 3).暂停2秒,选择‘北京
```python
|
Select下拉框

- Select类实现选项选择只适用于HTML原生态的
<select>+<option>
的下拉框。
案例
- 练习使用 Select 类的方式实现注册A地址选择操作,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| ```

- 当界面存在弹出框时,必须先处理掉弹出框才能继续其它操作!
- 类型 : - 自定义弹出框 - 可以直接通过web浏览器开发者工具查看到具体的元素信息 - 通过元素定位后直接可以处理掉· - JS弹出框 - 通过JS函数实现,通过web浏览器开发者工具无法查看到元素信息 - 常见 JS 弹出框形式:`alert(警告框)`、`confirm(确认框)`、`prompt(提示框)` - 不能通过元素定位进行处理

- 需求:打开注册A.html页面,完成以下操作: - 1).点击alert 按钮 - 2).关闭警告框 - 3).输入用户名:admin
```python
|
滚动条
滚动条处理
滚动条处理
- 所要操作的元素不在当前展示页,需要滑动滚动条才能找到。
- 定义Js字符串
js = "window.scrollTo(0,1000)"
- 执行Js字符串
driver.execute_script(js)

案例
- 需求:
- 打开注册A.html页面,完成以下操作
- 1).暂停2s,控制滚动条滑动到页面最底部
- 2).暂停2S,点击返回顶部按钮
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| ```
- 能编写脚本控制鼠标模拟右击、悬停手工交互操作


```python
import time from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver import ActionChains
driver = webdriver.Chrome()
driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
username = driver.find_element(By.ID,"userA")
action = ActionChains(driver)
action.context_click(username)
action.perform()
time.sleep(5)
driver.quit()
|
鼠标操作练习
- 练习一
- 需求:打开注册页面A,模拟鼠标悬停在’注册’按钮上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import time from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver import ActionChains
driver = webdriver.Chrome()
driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
btn = driver.find_element(By.TAG_NAME,"button")
action = ActionChains(driver)
action.move_to_element(btn)
action.perform()
time.sleep(5)
driver.quit()
|
- 练习二
- 需求:打开注册页面A,在用户名文本框上点击鼠标右键
- 练习三
- 需求:1、打开注册A,输入用户名 admin,暂停3秒钟后,双击鼠标左键,选中admin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import time from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver import ActionChains
driver = webdriver.Chrome()
driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/%E6%B3%A8%E5%86%8CA.html")
username = driver.find_element(By.ID,"userA") username.send_keys("admin") time.sleep(3)
action = ActionChains(driver)
action.double_click(username)
action.perform()
time.sleep(5)
driver.quit()
|
鼠标拖拽操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import time from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver import ActionChains
driver = webdriver.Chrome()
driver.get("file:///E:/203_%E9%BB%91%E9%A9%AC%E8%BD%AF%E4%BB%B6%E6%B5%8B%E8%AF%95/5.0%E8%AF%BE%E4%BB%B6/5.0%E8%AF%BE%E4%BB%B6/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/UI%E8%87%AA%E5%8A%A8%E5%8C%96V5.0%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/web%E7%AB%AF%E7%8E%AF%E5%A2%83/web%E8%AF%BE%E5%A0%82%E7%B4%A0%E6%9D%90/web/drop.html")
red = driver.find_element(By.ID,"div1") blue = driver.find_element(By.ID,"div2")
action = ActionChains(driver)
action.drag_and_drop(red,blue)
action.perform()
time.sleep(5)
driver.quit()
|
键盘操作(空)
元素等待
学习目标
- 理解元素等待的概念和作用
- 能使用元素等待方法来提供脚本运行效率
元素等待
认识元素等待

界面渲染和脚本运行速速那个快?
- 网络速度慢
- 电脑配置低
- 服务器处理请求慢
Time.sleep()
影响运行效率
元素等待概念 :
- 在定位页面元素时如未定位到,会在指定时间内一直等待的过程。
隐式等待
隐式等待

- 隐式等待
- 定位元素时,如果能定位到元素则直接返回该元素,不触发等待;
- 如果不能定位到该元素,则间隔一段时间后再去定位元素;
- 如果在达到最大时长时还没有找到指定元素,则抛出元素不存在的异常 NoSuchElementException。
driver.implicitly_wait(timeout)
- 隐式等待为全局设置(只需要设置一次,就会作用于所有元素)
- 当隐式等待被激活时,虽然目标元素已经出现了,但是还是会由于当前页面内的其他元素的未加载完成,而继续等待,进而增加代码的执行时长
案例
- 需求:打开注册A.html页面,完成以下操作
- 1).最大化窗口
- 2).使用隐式等待定位延时加载输入框,输入admin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| ```
- 显式等待 - 定位指定元素时,如果能定位到元素则直接返回该元素,不触发等待; - 如果不能定位到该元素,则间隔一段时间后再去定位元素; - 如果在达到最大时长时还没有找到指定元素,则抛出超时异常常TimeoutException

- `element = WebDriverWait(driver, 10, 1).until(lambda x: x.find_element_by_id("userA") )`
- 需求:打开注册A.html页面,完成以下操作 - 1).最大化窗口 - 2).使用显示等待定位延时加载输入框,输入admin
```python
|
隐式等待和显示等待对比


Frame切换
认识frame

- Frame HTML页面中的一种框架,主要作用是在当前页面中指定区域显示另一页面元素
Frame切换方法

多窗口切换
认识多窗口
- 多窗口 : 在HTML页面中,当点击超链接或者按钮时,有的会在新的窗口打开页面。

多窗口切换方法
多窗口切换方法
- 窗口切换:selenium 需要通过窗口的句柄来实现窗口的切换!
- 说明:在浏览器的一个生命周期内(开启到关闭), 任意一个窗口都有唯一的一个句柄值,可以通过句柄值完成窗口切换操作

案例
- 需求:打开‘注册实例.html’页面,完成以下操作
- 1). 点击‘注册A页面’链接
- 2). 在打开的页面中,填写注册信息
切换操作小结

窗口截图
窗口截图
UI自动测试统一运行时无人值守
错误信息记录不是十分明确
有截图结合错误信息方便快速分析错误
获取所有窗口句柄 :
driver.get_screenshot_as_file(imgpath)
- imgpath:图片保存路径
- 若路径包含文件夹,则需要先手动创建文件夹
- 可以拼接时间戳以防止文件名重复覆盖
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| ```
- 一种随机生成的信息(数字、字母、汉字、图片、算术题)等为了防止恶意的请求行为,增加应用的安全性。 - 注意:在自动化测试过程中,必须处理验证码,否则无法继续执行后续测试

- 要进行后续业务操就必须登陆,那自动化该如何处理这些验证码操作? - 去掉验证码、万能验证 - 都是开发来完成 - 万能验证码 : 生产环境和测试环境下采用,必须注意保密不要外泄万能验证码 - 码验证码识别技术 - 成功率不高,验证码种类繁多,不太适合 - 记录cookie

- Cookie概念 : - Cookie是由Web服务器生成的,并且保存在用户浏览器上的小文本文件,它可以包含用户相关的信息。 - Cookie数据格式:键值对组成(python中的字典) - Cookie产生:客户端请求服务器,如果服务器需要记录该用户状态,就向客户端浏览器颁发一个Cookie 数据 - Cookie使用:当浏览器再次请求该网站时,浏览器把请求的数据和Cookie数据一同提交给服务器,服务器检查该Cookie,以此来辨认用户状态。

- Cookie操作方法: - `driver.get_cookie(name)` 获取指定cookie - `driver.get_cookies()` 获取本网站所有本地cookies - `driver.add_cookie(cookie_dict)` 添加cookie - `cookie_dict` :一个字典对象,必选的键包括:"name" and "value"
- 需求:使用cookie实现跳过登录 - 1). 手动登录百度,获取cookie - 2). 使用获取到的cookie,达到登录目的,然后就可以执行登录之后的操作BDUSS是登录百度后的唯一身份凭证(*.baidu.com),拿到BDUSS就等于拿到帐号的控制权, 通行贴吧、知道、百科、文库、空间、百度云等百度主要产品。
- Selenium 常用的基本 Api 学习完成 - 通过不同操作步骤场景脚本编写来巩固学习记忆和理解 - 独立练习课后代码实现确认是否达到学习目标
- pytest 是 python 的一种单元测试框架,同自带的 UnitTest 测试框架类似,相比于 UnitTe&t 框架使用起来更简洁,效率更高。 - 在自动化测试中同样充当测试执行的功能!并且可以跟UnitTest互换
- 1.非常容易上手,入门简单,文档丰富,文档中有很多实例可以参考 - 2.支持简单的单元测试和复杂的功能测试 - 3.支持参数化 - 4.执行测试过程中可以将某些测试跳过,或者对某些预期失败的Case 标记成失败 - 5.支持重复执行失败的 Case - 6.支持运行由 Nose,UnitTest 编写的测试 Case - 7.具有很多第三方插件,并且可以自定义扩展 - 8.方便的和持续集成工具集成
```python
pip install pytest
pytest --version
|
基本使用
函数形式
1 2 3 4
| def testfunc(): """测试函数""" print("我是测试函数")
|
1 2
| # 终端执行 pytest -s .\001_打开网页.py
|
1 2 3 4 5 6 7 8 9 10 11 12
| import pytest
def testfunc(): """测试函数""" print("我是测试函数")
if __name__ == "__main__": pytest.main(['-s', '.\001_打开网页.py'])
|
类形式
1 2 3 4 5 6 7 8 9 10 11
| class TestDemo(object): """测试示例类"""
def test_method1(self): """测试方法1""" print("测试方法1")
def test_method2(self): """测试方法2""" print("测试方法2")
|
1 2
| # 终端执行 pytest -s .\001_打开网页.py
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import pytest
class TestDemo(object): """测试示例类"""
def test_method1(self): """测试方法1""" print("测试方法1")
def test_method2(self): """测试方法2""" print("测试方法2")
if __name__ == "__main__": pytest.main(['-s', '.\001_打开网页.py'])
|
特殊方法
- setup和teardown
- pytest 在运行自动化脚本的前后会执行两个特殊的方法,分别是setup和teardown。
- 在执行脚本之前会执行setup方法,在执行脚本之后会执行teardown方法。
- 有了这两个方法,我们可以在setup中进行获取驱动对象的操作,在teardown中进行关闭驱动对象的操作。
函数级别
- 运行于测试方法的始末,运行一次测试函数会运行一次setup和teardown。
1 2 3 4 5 6 7
| ```
- 运行于测试类的始末,在一个测试内只运行一次 setup_class 和 teardown_class,不关心测试类内有多少个测试函数。
```python
|
函数与类级别同时使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| ```
- 使用配置文件后可以快速的使用配置的项来选择执行哪些测试模块 - 注意 : - 1.在 Windows 系统下,pytest 配置文件中,不允许写注释信息 - 2.一个工程内只需要一个 pytest 配置文件,并且需要保证文件名正确 - 3.一般情况,只需要将 pytest 配置文件,置于工程根目录下 - 4.配置有 pytest 配置文件的工程,只需要打开命令行,输入 pytest 指令,即可执行测试
- 1.项目下新建 scripts 模块 - 2.将测试脚本文件放到 scripts 中 - 3.`pytest` 的配置文件放在自动化项目目录下 - 4.名称为 `pytest.ini` - 5.命令行运行时会使用该配置文件中的配置 - 6.第一行内容为`[pytest]`
```python
...
|


常用插件
学习目标
- 1.能够生成 pytest-html 测试报告
- 2.能够控制 pytest 函数执行的顺序
- 3.能够掌握 pytest 失败重试
测试报告
应用场景
- 自动化测试脚本最终执行是通过还是不通过,需要通过测试报告进行体现
安装
- 使用命令
pip install pytest-html
进行安装
使用
- 在配置文件中的命令行参数中增加
--html=用户路径/report.html
1 2
| addopts =-s --html=report/report.html
|
结果
- 在项目目录下会对一个 report 文件夹,里面有个 report.html 即为测试报告
控制函数执行顺序
应用场景
现实生活中,如果想下订单,必须先登录,我们可以通过插件的形式来控制函数执行的顺序。
安装
- 使用命令 :
pip install pytest-ordering
进行安装
使用
- 1.标记于被测试函数,
@pytest.mark.run(order=1/2/3/....)
- #扩展:序号支持正数和负数,以及正负混合
- #1。纯正数:数越小,优先级越高
- #2.纯负数:数越小,优先级越高
- #3.正负混合:正数先按照顺序执行,负数最后执行
- 2.根据order传入的参数来解决运行顺序
- 3.order值全为正数或全为负数时,运行顺序:值越小,优先级越高
- 4.正数和负数同时存在:正数优先级高
失败重试
应用场景
- 自动化测试脚本可能会使用到网络,如果网络不好可能最终会使脚本不通过。
- 像这种情况可能并不是脚本本身的问题,仅仅是因为网络忽快忽慢,那么我们可以使用失败重试的插件,当失败后尝试再次运行。
- 一般情况最终成功可以视为成功,但最好进行进行排查时候是脚本问题。
安装
- 使用命令
pip install pytest-rerunfailures
进行安装
使用
- 在配置文件中的命令行参数中增加
--reruns n
- 说明:正式脚本一般设置不超过3次 , 测试脚本设置1次即可
高级用法
跳过测试函数
应用场景
- 同一个软件在不同的设备上可能会有不同的效果,比如,iOS的3dtouch操作是需要6s以上设备支持的,6和6s都可以安装同一款应用,如果设备不支持,那么根本没有必要去测试这个功能。此时,我们可以让这种函数进行跳过。
数据参数化
应用场景
- 登录功能都是输入用户名,输入密码,点击登录。但登录的用户名和密码如果想测试多个值是没有办法用普通的操作实现的。数据参数化可以帮我实现这样的效果。
方法名
1 2 3 4 5
|
@pytest.mark.parametrize(argnames, argvalues, indirect=False, ids=None, scope=None)
|
- 一个参数使用方式
- 1.argnames 为字符串类型,根据需求决定何时的参数名
- 2.argvalues 为列表类型,根据需求决定列表元素中的内容
- 3.在测试脚本中,参数,名字与 argnames 保持一致
- 4.在测试脚本中正常使用
PO模式
学习目标
- 深入理解方法封装的思想
- 能够使用方法封装的思想对代码进行优化
- 深入理解PO模式的思想
- 熟练掌握PO模式的分层思想
存在的问题分析

- 问题
- 元素定位的代码对页面特别依赖,一旦页面发生变化所有用到该页面的元素定位代码都需要进行修改
- 存在大量元素定位代码冗余
认识PO模式

页面对象

- 编写步骤:
- 定义页面元素实例属性
- 定义页面业务实例方法
- 一个页面可能存在多个业务方法,如登陆页面:登陆、找回密码等
- 抽取定位信息到实例属性
- 将元素定位的信息抽离到实例属性中进行统一管理,方便维护
优化封装

- PO页面定位元素受隐式等待影响
- 运行效率低:隐式等待依赖于界面的加载
- 解决方式:给所有的元素等待操作加上显示等待
- 模拟输入可能受输入框默认值影响输入的测试数据
- 影响测试结果:输入数据就会变成:默认值+输入数据
- 解决方式:每个模拟输入之前加上清除动作
元素定位

- 二次封装
- 对工具原有提供的方法或函数添加个性化设置的代码,
- 保障原有作用的情况下加上了个性化功能的封装

模拟输入


案例

- 对 pshop 首页进行 PO 封装
- 通过调用二次封装后元素定位方法和模拟输入的方法实现定位和输入
数据驱动
学习目标
- 理解数据驱动的作用
- 知道UI自动化测试数据驱动实现思路
认识数据驱动
数据驱动概念
- 数据驱动 : 以数据来驱动整个测试用例的执行,也就是测试数据决定测试结果

数据驱动实现方式

- 常见数据存储方式 :
- 从文件读取数据,如JSON、excel、xml、txt等格式文件
- 从数据库中读取数据
- 调用接口、本地封装代码获取
PO数据驱动实现
组织Tpshop登陆测试数据

封装测试数据读取函数


测试用例参数化引入

数据驱动总结
- 1、UI自动化测试中数据驱动的核心是:
- 利用参数化技术使用同样的测试步骤来执行不同的测试数据,验证各种测试情况
- 将测试数据和测试脚本分离,编写完成操作脚本后,将重点放到数据的维护和构建上
- 2、数据存储的方式有多种,并不限于 json 文件存储形式,只要最终提供给参数化的数据是符合规定格式的即可。