web自动化-电商实战
四、Web自动化实战-电商项目个人中心用例设计和实现(day28)
1. 需求分析与用例设计
项目地址
核心业务:购物
个人中心业务:
业务管理模块
订单管理:数据展示、筛选、交互
售后管理:数据展示、筛选、交互
商品收藏:数据展示、筛选、交互
财产中心模块
- 我的积分:数据展示、筛选、交互
资料管理模块
- 个人资料:文件上传、表单
- 收货地址:数据展示、管理(增删查改)、表单
- 安全设置:修改、表单
- 我的消息:数据展示、筛选、交互
- 我的足迹:数据展示、筛选、交互
- 留言问答:数据展示、筛选、交互
必测的三个功能:
收货地址:数据展示、管理(增删查改)、表单
订单管理:数据展示、筛选、交互
个人资料:文件上传、表单
前置条件
- 启动浏览器并登录
- 准备头像图片文件
用例步骤
进入个人中:http://116.62.63.211/shop/personal/index.html
获取旧头像src属性:/html/body/div[4]/div[3]/div/dl/dd[1]/img
点击修改按钮:/html/body/div[4]/div[3]/div/dl/dd[1]/span/a
为input选择图://[@id=”user-avatar-popup”]/div/div[2]/form/div[2]/div/input
点击上传://[@id=”user-avatar-popup”]/div/div[2]/form/button
获取系统提示://p[@class=”prompt-msg”]
断言:系统提示 == “上传成功”
重新进入个人中心:http://101.34.221.219:8010/?s=personal/index.html
获取新头像src属性:/html/body/div[4]/div[3]/div/dl/dd[1]/img
断言: 旧头像src属 != 新头像src属性
后置操作
1.关闭浏览器
2. 代码实现
1 | import time |
上传按钮不能交互报错:
使用强制等待(隐式等待只能判断元素是否存在),发现变为可点击
如何写显式等待代码:
思路:能不能变成可点击,能不能自动变成可点击,如何判断它是可以点击的
1.难题:不能点击
2.难题:不能得到系统提示
1 | def func(d): |
等待策略中做选择:
- 可维护性,大于技术深度
遇到错误:
- 出错类型
- 出错原因
- 出错解决办法
五、Web自动化实战-电商项目复杂表单元素自动化操作(day29)
1. 引入专业测试框架目录结构
- 安装依赖
- 启动框架
- 查看日志
- 查看报告
2. 收货地址用例设计
收货地址: 数据展示、管理(增删查改)、表单
默认地址规则:
- 没有默认地址时,最新的地址就是默认
- 有默认地址时,标记默认的地址就是默认
- 只会有1个默认地址
1. 前置操作
- 启动浏览器
- 登录账号
- 进入【我的地址】:http://116.62.63.211/shop/useraddress/index.html
- 创建默认地址
2. 用例步骤
创建用例
有默认地址场景:
- 创建新地址(参数:非默认)
- 点击【新增地址】:/html/body/div[4]/div[3]/div/div/button
- 输入【别名】:/html/body/div[1]/form/div[1]/input
- 输入【姓名】:/html/body/div[1]/form/div[2]/input
- 输入【电话】:/html/body/div[1]/form/div[3]/input
- 选择【省份】:
- 点击元素加载选项:/html/body/div[1]/form/div[4]/div[1]/a/span
- 点击选项完成选择:/html/body/div[1]/form/div[4]/div[1]/div/ul/li[15]
- 选择【城市】:
- 点击元素加载选项:/html/body/div[1]/form/div[4]/div[2]/a/span
- 点击选项完成选择:/html/body/div[1]/form/div[4]/div[2]/div/ul/li[2]
- 选择【区县】:
- 点击元素加载选项:/html/body/div[1]/form/div[4]/div[3]/a/span
- 点击选项完成选择:/html/body/div[1]/form/div[4]/div[3]/div/ul/li[4]
- 输入【详细地址】://*[@id=”form-address”]
- 切换【默认】:/html/body/div[1]/form/div[6]/div
- 点击【保存】:/html/body/div[1]/form/div[7]/button
- 断言:
- 系统提示:/html/body/div[4]/div/p == “操作成功”
- 默认地址的别名 != 本次输入的别名
没有默认地址场景:
- 创建新地址(参数:非默认)同上
- 断言:
- 系统提示:/html/body/div[4]/div/p == “操作成功”
- 默认地址的别名 == 本次输入的别名
删除用例
有默认地址场景:
- 删除地址
- 点击【删除】://*[@id=”data-list-5605”]/div[2]/a[3]
- 点击【确定】://*[@id=”am-modal-ubh1v”]/div/div[3]/span[2]
- 断言:
- 系统提示 = “删除成功”
- 新默认地址别名 = 旧默认地址别名
没有默认地址场景:
- 创建新地址(参数:非默认)同上
- 断言:
- 系统提示 = “删除成功”
- 新默认地址别名 != 旧默认地址别名
编辑用例
有默认地址场景:
- 编辑地址并设为默认
- 点击【编辑】://*[@id=”data-list-5610”]/div[2]/a[1]
- 点击【默认地址】:/html/body/div[1]/form/div[6]/div
- 断言:
- 系统提示 = “操作成功”
- 新默认地址别名 != 旧默认地址别名
没有默认地址场景:
- 自动指定最新地址(默认地址只有一个)
3. 后置操作
- 删除默认地址
- 删除测试新增地址
- 关闭浏览器
4. 整理前后置关系
- 前置:启动浏览器、登录
- 场景A:有默认地址
- 前置:进入我的地址,创建1默认地址+1个非默认地址
- 用例1:创建
- 用例2:编辑
- 用例3:删除
- 后置:删除全部地址
- 场景B:没有默认地址
- 前置:进入我的地址,创建2个非默认地址
- 用例1:创建
- 用例2:编辑
- 用例3:删除
- 后置:删除全部地址
- 场景A:有默认地址
- 后置:关闭浏览器
3. 收货地址用例实现
1. 实现fixture(前置、后置)
1 | def new_address(driver, alias, name, tel, province, city, county, address, default=False): |
2. 实现测试用例
场景A:有默认地址
前置:创建1默认地址+1个非默认地址
- 用例1:创建
- 用例2:编辑
- 用例3:删除
后置:删除全部地址
1. iframe处理
原因:把另一个网页的内容,嵌入当前页面显示,但是元素不属于当前页面,无法定位
解决方案: 让selenium切换到另一个网页
1 | # 进入iframe |
具体方法:
- 定位到iframe元素、调用selenium切换到这个元素(进去)
- 定位需要iframe中的元素 (定位)
- iframe中的元素定位完毕之后,切回到主页面(退出)
- 定位主页面的元素 (恢复正常操作)
2. 点击被拦截解决方案
原因:元素被遮挡或元素位置移动
1 | # 使用JS强制点击 |
3. 下拉选择处理
- 原生
<select>:使用Selenium封装函数 div实现的下拉:模拟用户操作(点击加载选项 → 点击选择选项)
六、Web自动化实战:POM设计模式深度封装流程(day30)
1. POM是什么
Page Object Model
- 字面翻译:页面 对象 模型
- 本质内涵:把页面进行面向对象式封装
2. 为什么使用POM
学习Python语言的不同阶段:
- 脚本:简单,不可重用,适合代码量少,临时使用场合
- 函数:基本封装,可以重用,适合代码适中,多次使用场合
- 面向对象:深度封装,隐藏细节,适合代码规模大、关系复杂的场合
POM的价值:
- 将页面内容(元素、网页、文本)和交互(点击、输入)通过面向对象方式深度封装
- 便于代码复用,简化用法,隐藏细节
- 中大型UI测试项目必备基础技巧
3. 怎么样使用POM
1. 创建BasePage
抽象类,不代表任何具体页面,包含大部分页面可能用到的通用成员:
- 保存
driver对象:控制真正的浏览器 - 保存
wait对象:实现显式等待 - 获取系统提示
- 通过JS进行强制点击
- 其他通用功能
注意:避免重复封装Selenium已有方法(如find_element):
1 | # 反面典型 - 无需重复封装 |
2. 创建Page
具体页面类,代表每个具体页面,包含:
- 该页面的独有元素内容和交互方式
- 为不同页面创建不同的类
- 在类中为不同操作创建方法
- 在类中为页面元素创建可复用元素
3. 使用Page
在测试用例中使用Page对象,而非直接使用Selenium:
1 | # 用例中使用示例 |
4. POM特点总结
- 面向对象抽象:
- 相似页面可复用元素定位
- 大部分页面可复用交互逻辑
- 灵活方法定义:
- 自定义方法名称、参数、返回值
- 方法间自由调用
- 子类可重写同名方法
- 深度封装细节:
- 用例只需关心操作步骤,不关心实现细节
- 页面变化(元素/交互变更)时用例无需修改
练习
- 将登录页面进行POM封装,供fixture使用
- 将头像上传页面进行POM封装,供测试用例使用
1 |

