自动化
2025-03-26 23:23:53 0 举报
AI智能生成
"智能化系统管家"是一款拥有先进自动化技术的文件管理系统,专门设计来优化个人和企业的文档整理流程。本软件透过人工智能算法核心,实现文件的智能分类、存储与检索,大大提高用户的工作效率。它的文件类型识别能力准确无误,无论是常见的Word文档、Excel表格还是图片与视频文件,都能快速准确识别。除此之外,系统提供的定制界面异常简洁,同时具备深度学习功能,能够不断适应并满足用户的个性化需求。任何企业级应用,都能在这款自动化助手的帮助下,将文件管理升级到全新的效率高度。
作者其他创作
大纲/内容
自动化基础
概述
执行
搭建测试环境
部署工程包
在实际开发环境,研发团队中也叫持续集成/每日集成/每日构建
设计编写用例,方案,需求等
执行用例
按照操作步奏
对比:实际结果与预期结果
标注:执行结果
提交bug
提交缺陷
分层自动化
UT(检查代码)
白盒测试
自己写代码,测开发写的代码
开发在做
自动化率100%
IT(子系统)
service层
灰盒测试(既可以黑盒也可以白盒)
接口自动化
自动化率50%-60%
下层为上层提供服务;上层调用下层接口(掉用于被调用的接口)
UI层
针对单个功能,进行自动化用例覆盖
自动化率20%-30%
覆盖主要/核心功能的基本流、正向流(主要流程)
why
节约成本
软件产品
熟悉业务产品需求
系统架构、技术实现,人
招聘人
人
类似技术,系统架构
在相同或类似的行业做过
落地执行
大批量用例编写、管理(维护、增删改)
维护:修改别人的测试用例,如果不好修改就自己重写
回归测试
需求变更频率
需求变化快,因为要抢占市场,更快得到用户反馈,相应
需求变更涉及到的自动化用例,必须全部回归测试pass,才能封板上线
自动化测试与人工测试是相互依赖的
简单
工具
效率高
企业需求
成本低
质量高
生产频率快
快速发布版本,加调迭代频率,保障软件质量
重复的,繁琐的,比较难实现的,交给机器执行,释放人力
人力思维,分析,设计
测试难点,企业现状
自动化率
自动化发现bug数
目的不是发现bug,而是释放人力,提高效率
发现bug数不会超过10%,发现bug大多数时候手工来实现
Fail
测试环境
测试数据
排除上面两个后,有可能是个bug
工具
自动化测试
功能
UI层(也叫web页面自动化)
QTP(UFT)(更多用录制脚本测试)
selenium
RFS(robotframework)
LR
service层
soapui(测接口)
unit层
unittest
testing
性能
LR(都是基于BS架构的)
Jmeter(开源的)
RF介绍与安装
RF能做哪些自动化
web自动化
selenium2Library
接口自动化
HTTPlibrary(request)
移动自动化
IOSlibrary
测试库
标准库:内库
扩展库:安装
RF安装
1:Python安装
只支持Python2,不支持Python3
Python.org下载Python2
后缀:.py文件
2:setuptools与pip安装
方便管理Python包,第三方报,工具
easy-install第三方Python报名
:3:pip安装
方便安装、更新相应包的版本
pip install robotframework====2.9
pip show robotframework
4:robotframework
5:wxpython
6:robotframework-ride
生成快捷键方式D:python27\python27.exe -c"from robotide import main;main()"
web自动化
selenium
selenium1.0
IDE
selenium-RC
selenium2.0
webdriver
默认支持Firefox
Google,
web前段
HTML表现形式
关注标签<title></title>
调试工具
Firefox
firebug
firepath
IE
F12
chrome
Ctrl+shift+I
RF+selenium2library
下载selenium2Library
app自动化
app手工测试
app测试基础知识
app应用的系统架构
app应用的系统架构和web应用系统架构一样是分三层
用户端
应用服务器
数据服务器
app项目环境(后端)
一般, 公司开发/ 测试人员会使用不同的环境, 以隔离工作过程中彼此的干扰, 同时, 上线给用户使用的产品也会单独部署环境
环境
开发环境
测试环境
预发布环境
生产环境
app发布平台(前端)
铺垫
对于web而言, 前端代码是随着后端服务一起打包发布的
如果app用框架嵌套了浏览器, 通过H5技术以网页的形式请求服务, 那么效果同上
app开发完成后, 相应的开发人员打包应用程序, 由测试人员进行安装
安卓: apk格式的安装包
IOS: ipa格式的安装包
发布形式
1 测试人员使用
开发人员把安装包传给测试人员
应用内侧发布平台
蒲公英
fir.im
2 实际用户使用
应用的线上发布平台
安卓: 豌豆荚, 应用宝, 360手机助手, 各类手机品牌商城等
IOS: 主要 AppStore, iTools, 爱思助手等
app项目
app项目说明
项目概述
所使用的app项目案例叫 学车不 , 可以帮助广大用户在线学车, 如, 在线进行模拟考试, 利用自己零碎时间进行驾考学习
项目功能结构
学车
banner
功能标签
学习进度
签到签退
预约训练
充值缴费
在线课堂
驾考题库
约考助手
学车头条
驾考圈
功能标签
最新
学车趣事
我炫车
学车问答
晒驾照
学车技巧
发布
浏览
点赞
评论
知道
略
我的
略
app应用测试要点
功能测试
兼容性
安装/卸载/升级测试
交叉事件测试
push测试
性能测试
CPU
内存
流量测试
电量测试
流畅度测试
启动速度
用户体验测试
稳定性测试
业务功能测试
显性需求
根据软件需求文档的内容, 验证app各个功能的实现
隐性需求
相关业务: 功能影响到的相关业务
其他角度: 分支流程, 逆向操作, 异常操作
补充精简: 测试策略, 业务知识, 测试经验
兼容性测试
1 手机型号
Android: 三星, 小米, OPPO, 华为
2 系统版本
Android: 4.4 5.1.6.0 7.0
ios: 9.x 10.x
3 屏幕尺寸, 分辨率
尺寸 5.5 4.7
分辨率 1080*1920 720*1280
4 网络
2G 3G 4G 5G WIFI
5 应用兼容性
与手机硬件兼容
与外部硬件设备兼容
与操作系统软件
与其他app兼容
安装卸载升级测试
安装
正常场景
1 在不同的操作系统版本上安装
2 从不同的安装渠道安装 (app商城, 手机助手, 直接下载安装包)
3 不同的安装路径 (安装到手机, 安装到SD卡上)
异常场景
1 安装时出现异常 (关机, 断网), 恢复后能否继续安装
2 安装时存储空间不足
3 安装时手动取消后, 再次安装
4 正在运行时, 覆盖安装
5 低版本覆盖高版本
6 卸载后的安装
卸载
1 正常卸载 (手工卸载, 工具卸载)
2 运行时卸载
3 取消卸载
4 卸载异常中断
5 卸载后无数据残留
升级
1 从邻近版本升级
2 跨版本升级
3 不同渠道升级
4 升级成功提醒 (可不提醒, 可以提示升级, 提示强制升级)
5 应用内升级时非WIFI提醒
交叉事件测试 (中断测试)
1 app运行时接打电话
2 app运行时收发信息
3 app运行时查看应用推送
4 app运行时街上蓝牙设备
5 app运行时接收文件弹窗的提醒
6 app运行时旋转屏幕
7 app运行时切换网络
8 app运行时使用相机, 计算器等手机自带应用
9 app运行时电量告警, 插拔充电器
Push消息测试
消息推送场景
产品角度: 功能需要, 如: 资讯类产品的新闻推送, 工具类产品的公告推送等等
运营角度: 活动需要, 如: 电商类产品的促销, 游戏类产品召回用户等等
消息推送原理
1 Pull
客户端每隔固定时间主动向服务器获取信息, 若有更新信息, 则发送给客户端
2 Push
当服务器有更新信息时, 主动发送给客户端
对比
push方式 比 pull 方式更好
消息推送的方式
1 操作系统级别的消息推送服务
Android 和 IOS
2 调用第三方推送平台
手机厂商
小米推送, 华为推送等等
第三方平台
友盟, 阿里云, 百度云
3 自己搭建推送服务器
好处: 功能好, 性能强, 安全性高
缺点: 成本高
Push推送设置
app服务器设置
针对的用户群体: 全部, 部分, 特定
推送的频率
手机端设置
推送是否接受通知, 是否显示标号
关注点
1 Push消息是否按照指定业务规则发送
2 当Push消息是针对特定用户时, 检查收到Push的用户是否相符
3 设置不接受推送消息时, 用户是否能收到Push消息
4 收到Push消息, 是否能正常打开
5 app在前台使用时, 收到Push消息如何提示
6 app在后台运行时, 收到Push消息如何提示
7 app离线, 是否能收到Push消息
性能测试
app性能测试常见指标
CPU
发热问题
内存
内存溢出/ 内存泄漏
流量
电量
启动速度
冷启动 / 热启动
流畅度
测试关注点
app使用时对CPU, 内存的占用情况
app使用是否流畅
app使用时电量, 流量消耗情况
app启动时间是否过长
性能测试工具之GT
简介
https://gt.qq.com/
安装
GT有两种版本
1 可独立安装的GT, 就像普通app一样安装
2 GT SDK: 将GT的SDK嵌入到被调测的应用的工程里
使用
注意点
部分功能, 需要root权限
步骤
1. 进入AUT界面, 选择被测程序和测试指标
2. 设置参数, 点击右上角的"编辑"按钮, 然后选中想测试的参数将其拖拽到已关注区域
点击"完成"按钮, 点击红点即可开始监控
3. 执行测试之前可以打开日志抓取, 方便发生问题时定位
4. 点击开始监控按钮, 打开被测app, 悬浮框会出现在你要测试的应用上
5. 查看数据采集结果
CPU
知识点
GT工具提供两个CPU的监控指标: CPU 和 Jiffies
CPU: 整机的CPU使用水平, 就是当前手机的CPU整体使用率
Jiffies: 表示自开机以来, 应用程序消耗的CPU的时间片的总数
CPU性能问题产生的影响
1 CPU使用长时间处于90%以上
2 手机发热, 耗电量增加
3 反应变慢
测试过程
需求
打开被测app, 实际使用app, 查看CPU指标是否正常
测试方法
1 打开GT工具, 配置CPU监控指标 (可配置告警阀值)
2 进入被测app, 操作各个模块的业务, 观察运行时CPU指标
app运行时, CPU是否有快速飙升
app运行时, CPU是否长时间处于90%以上
3 查看CPU运行结果
4 保存CPu详细数据, 并查看CPU的详细的数据统计
内存
知识点
GT工具提供两个内存的监控指标: PSS 和 Private dirty
PSS: 整机的实际使用的物理内存
Private dirty: 进程独占内存, 也就是进程销毁时可以回收的内存容量
常见的内存问题
1 内存泄漏 memory leak, 是指程序在申请内存后, 无法释放已申请的内存空间, 如果一直存在这个行为, 无论多少内存, 迟早会被占光
2 内存溢出out of memory, 是指程序在申请内存时, 没有足够的内存空间供其使用
二者关系: 内存泄漏一定会最终导致内存溢出
内存问题产生的影响
1 程序实际使用的内存PSS持续增长
2 程序出现闪退 (可能是内存溢出)
测试过程
需求
打开被测app, 实际使用app, 查看内存指标是否正常
测试方法
1 打开GT工具, 配置内存监控指标 (可配置告警阀值)
2 进入被测app, 操作各个模块的业务, 观察运行时CPU指标
app运行时, PSS是否持续增长
app运行时, 程序是否出现闪退 (可能是内存溢出)
3 查看内存运行结果
4 保存并查看内存的详细的数据统计
流畅度
知识点
GT工具提供了流畅度的监控指标: FPS
FPS就是Frames per sencond: 一秒内绘制的帧数
动画片就是由一张张画出来的图片连贯执行产生的效果, 当一张张独立的图片切换速度足够快的时候, 会欺骗我们的眼睛, 以为这是连续的. 反之, 当图片切换不够快的时候, 会被人眼看穿, 反馈给用户的体验就是所谓的卡顿现象
流畅度影响效果
1 想要让大脑觉得动作是连续的, 至少是每秒10~12帧的速度
2 想要达到流畅的效果, 至少需要每秒24帧
3 较好的流畅度效果, 需要每秒60帧以上
测试过程
需求
打开被测app, 实际使用app(页面切换和页面滑动), 查看FPS指标是否正常
不同于CPU, 内存, 当页面多为静态时, FPS值小是正常, 如页面数据是动态加载, FPS值比较大
测试方法
1 打开GT工具, 配置流畅度监控指标 (在参数项中配置)
2 进入被测app, 操作页面切换或者滑动, 观察流畅度指标
3 查看流畅度运行结果
4 保存并查看内存的详细的数据统计
流量
知识点
GT工具提供了流畅度的监控指标: NET
流量: 手机通过运营商的网络访问 Internet, 运营商替我们手机转发数据报文, 数据报文的总大小(字节数) 即流量, 数据报文是包含手机上下行的报文
常用的流量测试方法
1 统计测试法: 获取应用程序的收发数据报文, 统计对应的流量
2 抓包测试法: 主要是利用 Tcpdump 或 Fiddler 抓包, 导出 pcap 文件, 再去wireshark中打开分析
测试过程
需求
打开被测app, 实际使用app(消耗网络流量), 查看流量指标是否正常
测试方法
1 打开GT工具, 配置流量监控指标
2 进入被测app, 消耗流量, 观察流量指标
3 查看运行结果
4 保存并查看流量的详细的数据统计
电量
知识点
GT工具提供了电量的监控指标: 电流, 电压, 电量, 温度
电量测试: 就是测试移动设备电量消耗快慢的一种测试方法, 一般用平均电流来衡量电量消耗速度
常见的耗电场景
定位, 尤其是调用GPS定位
网络传输, 尤其是非wifi环境
屏幕亮度
CPU频率
内存调度频率
测试过程
需求
调整屏幕亮度到最大
打开被测app, 进行各种业务测试, 并且注意不同的网络环境下进行测试
使用过程中, 间隔几分钟就锁屏或者唤醒屏幕
测试方法
1 打开GT工具, 配置插件, 点击耗电数据采集
2 选择采样频率, 屏幕亮度和采集参数, 点击开始
3 进入被测应用, 操作业务
4 测试完成后, 回到参数页面, 点击停止录制, 保存数据
启动速度
知识点
app的启动分为冷启动, 热启动
冷启动: 指app被后台杀死后, 在这个状态下打开app, 这种启动方式就是冷启动
热启动: 指app没有被后台杀死, 仍然在后台运行, 通常我们再次去打开这个app, 这种启动方式叫热启动
测试方法
使用adb命令
小结
测试方法
GT
CPU
内存
流畅度
流量
电量
adb命令
启动速度
测试结果分析
与基准数据对比
基准数据来自于产品经理, 或者以往数据的积累
横向对比, 拉上竞品一起测试 (目前采用的比较多的方法)
用体验测试
UI界面
对照UI交互设计文档, 检查每个界面设计菜单, 对话框, 窗口, 风格, 布局等等
注意: 图片, 按钮(选中效果), 字体大小/颜色/对齐方式等等
易用性
引导页
菜单层次是否太深
交互流程分支是否太多
完成业务操作的步骤是否过多
界面中按钮可点击 范围是否适中
横竖屏
横竖屏切换是否正常
特别关注app的表格在屏幕切换时的表现
其他辅助功能
重点关注"字体放大""语音转换""多点触碰"等等功能
稳定性测试
通过长时间对应用程序进行无序操作, 检验应用程序是否出现异常, 如: 程序闪退, 程序无响应
稳定性测试工具: Monkey
Monkey 是一个命令行工具, 由安卓官方提供
测试人员可以通过Monkey来模拟用户的触摸,点击,滑动等操作(操作事件是随机的), 从而实现对app压力测试和稳定性测试
稳定性测试的时机
一般在产品比较稳定, bug比较少的时候再用 Monkey去测试应用的稳定性
小结
如何测试app?
要从如下这些方面来进行测试
功能测试
兼容性测试
安装卸载升级测试
交叉(中断)事件
Push测试
性能测试
CPU
内存
流量
电量
流畅度
启动时间
用户体验
稳定性测试
补充
经过了上述各方面的充分测试, 产生测试报告, app就可以上线了
app自动化入门
自动化环境搭建
基本概念
什么是移动端
手机, 平板, 各种移动平台的智能设备
什么是移动端测试
移动端测试和web测试有什么区别
本质是相同
移动端有自身的特点: 系统, 内存, CPU, 网络, 移动端测试更加复杂
为什么要学习移动自动化
外需
用户多 -> 产品多 -> 岗位需求多
内需
高薪
自动化测试是10k的分水岭
薪资交叉重叠的区域, 取决于测试思维能力和表达能力
环境分析
步骤
1 工具选择
其实就是选择用哪个自动化工具去测试什么手机, 以及使用什么高级语言
1. Appium 自动化工具
开源, 跨平台, 支持多语言, 是目前主流的移动自动化工具之一
2. Android 手机模拟器
方便演示
3. python 语言
2 分析结果
Appium
python
appium-python-client
Android
模拟器
SDK
JDK
安装配置
注意点
1 操作系统的位数
2 安装路径规范化: 不要有中文, 空格, 特殊字符
JDK
安装
推荐1.8版本
配置环境变量
验证
命令行输入 java -version
Android SDK
解压
Android SDK文件夹解压到指定目录 ( 我的解压目录 D:\android-sdk )
配置环境变量
1 找到环境变量
2 在系统变量下新建 -> 变量名 ANDROID_HOME -> 变量值 D:\android-sdk -> 点击确定按钮
3 在系统变量下的path中, 添加
;%ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools;%ANDROID_HOME%\build-tools\25.0.0;
点击确定按钮
验证
命令行输入 adb
提示内容不是 "不是内部或外部命令"
夜神模拟器
安装
运行 nox-6.3.exe 进行安装
配置环境变量
把安装目录下的bin目录, 配置到 path中 如, 我的是 D:\Program Files\Nox\bin
配置 nox_adb 工具
如果AndroidSDK下的 adb.exe 和 模拟器下的 nox_adb.exe 版本不一致, 会产生冲突
解决冲突
1 删掉 D:\Program Files\Nox\bin 目录下的 nox_adb.exe
2 复制 D:\android-sdk\platform-tools 下的 adb.exe 到 D:\Program Files\Nox\bin , 并把复制过来的 adb.exe 改名为 nox_adb.exe
解决冲突后, 就可以通过命令操作手机模拟器了, 可以通过代码来自动化操作手机模拟器
配置夜神模拟器
1 在设置中将平板模式切换为手机版, 同时选择较低的分辨率[需要重启模拟器]
2 进入模拟器: 打开USB调试, 显示指针位置
1. 打开开发者模式
2. 打开 USB 调试
3. 打开指针位置
验证
命令行输入 adb devices , 如果显示 127.0.0.1:62001 device 则说明夜神模拟器的配置是ok的
Appium
安装
1 启动安装程序
2 设置为所有人安装
配置
启动 Appium 桌面程序, 点击 Edit Configurations
配置 ANDROID_HOME 和 JAVA_HOME , 选择 保存并重启
点击 start server, 页面日志没有红色叉叉就ok了
python相关
安装 appium-python-client 包
通过命令行运行 pip install appium-python-client
作用: 让 appium 认识 python 的代码
验证方式
通过命令行运行 pip list 查看是否存在 appium-python-client
扩展
关于 pip
如果你本机同时装有 v2.x 和 v3.x 的 python 那么注意
pip 是为 v2.x 的 python 去安装第三方库/包
pip3 是为 v3.x 的 python 去安装第三方库/包
如果你本机只装有一个版本的python
使用 pip 命令即可
工具介绍
Android SDK
SDK 是什么?
SDK 全程: Software Development Kit, 为程序开发提供各种支持, 如: 示例, 接口, 资源库
理解一下什么是一流公司做标准
SDK Manager
用于管理 Android SDK 各种工具包的版本, 为其安装卸载升级提供支持
Appium
特点
开源 免费
支持多语言, 如: python, java, php, js, ruby, C#等
跨平台
工作原理
1. 测试人员写 python 自动化测试脚本, 通过 http 协议传给 appium 服务器
2. appium 服务器接收到脚本后, 会进行转化, 交给不同的移动端
如果是ios的, 那么就调用手机里的 bootstrap.js 帮你执行自动化测试
如果是Android的, 那么就调用 bootstrap.jar
3. 脚本执行完成后, 消息原路返回
adb调试工具
总体介绍
概念
ADB 全名 Android Debug Bridge, 是一个调试工具
安卓开发人员, 一定要掌握
测试工程师, 在测试Android手机的应用时, 会使用到
作用
adb工具可以在电脑端通过控制台命令操作移动端(手机或模拟器)
步骤
1 打开 adb 服务
2 打开并连接移动端
3 在命令行输入 adb 命令
构成和工作原理
adb包含3个部分
1 client 端
运行在PC上(命令行工具), 用来发送 adb 命令
2 server 端
运行在PC上, 用来管理 client 和 daemon 之间的通信
3 daemon 守护进程
运行在移动端, 用来接收并执行 adb 命令
adb常用命令
获取包名和界面名
概念
包名: 决定程序的唯一性 (不是应用的名字)
多开?
实现方案1: 手机分身
实现方案2: 改包名
界面名: 目前可以理解, 一个界面名对应着一个界面
应用场景
自动化测试需要通过代码来告诉手机, 测试哪个应用的哪个界面, 所以需要使用命令提前获取包名和界面名
命令
adb shell dumpsys window windows | findstr mFocusedApp
windows的命令行 使用 findstr 帮你匹配字符串进行过滤
mac/linux 上用 grep 代替 findstr
示例
1 在模拟器打开"设置"应用
2 输入对应的命令获取包名和界面名
mFocusedApp=AppWindowToken{20487a71 token=Token{b1eb018 ActivityRecord{1c9127fb u0 com.android.settings/.Settings t5}}}
包名: com.android.settings
界面名: .Settings
文件传输
双向传输: 1 PC发送文件到手机 2 从手机获取文件到PC
应用场景
1. 将手机需要的 测试数据(数据库文件)在电脑上调整好, 发送给手机
2. 从手机获取数据或者日志
命令格式
adb push 电脑的文件路径 手机上的文件夹路径
adb pull 手机上文件的路径 电脑端文件夹路径
示例
将桌面的 a.txt 发送到手机 sd 卡
adb push C:\Users\57769\Desktop\a.txt /sdcard
把手机 sd 卡的 a.txt 拉取到桌面
adb pull /sdcard/a.txt C:\Users\57769\Desktop
注意点
\ 是 windows 上的分隔符
/ 是 mac 和 linux 上使用的分隔符
获取app启动时间
命令
adb shell am start -W 包名/启动名
启动名: 默认的启动所加载的界面的界面名
示例
冷启动
启动耗时较久
热启动
启动较快
adb shell am start -W com.android.settings/.Settings
结果
ThisTime
TotalTime
WaitTime
如何判断启动的性能是通过测试的?
1. 需求文档
2. 参考同类软件, 启动时间不超出1倍
获取手机日志
应用场景
获取手机日志, 方便开发人员定位bug, 显得更专业
命令
adb logcat
步骤
1. 打开手机/模拟器
2. 命令行输入 adb logcat 回车
3. 操作app 复现 bug
4. 抓取日志, 发送给开发人员进行定位
补充
可以在Android SDK下的 tools 目录下查找 ddms.bat, 也可以用于获取日志, 更好用
注意
输出日志中, 找 at 关键字
把错误级别是 E 的信息复制出来, 发给开发人员
E (error)
安装卸载
命令
从手机卸载某个程序包
adb uninstall 包名
安装 apk 到手机
adb install apk的路径
示例结果
卸载并安装 "安智市场"
$ adb shell dumpsys window windows | findstr mFocused
mFocusedApp=AppWindowToken{264301e token=Token{fd82c59 ActivityRecord{37c7d8a0 u0 cn.goapk.market/com.anzhi.market.ui.RecommendInstallNewActivity t10}}}
$ adb uninstall cn.goapk.market
$ adb install C:\Users\57769\Desktop\anzhishichang.apk
其他命令
adb start-server
启动adb服务
adb kill-server
关闭adb服务
adb devices
获取当前电脑已经连接的设备列表
注意
如果模拟器或手机持续运行, 此时重启adb服务, 会连不上手机
解决办法(针对夜神模拟器)
1. 重启模拟器
2. 执行命令 nox_adb connect 127.0.0.1:62001
adb shell
进入到安卓手机内部的 linux 系统命令行中
可以通过 exit 进行退出 linux 系统命令行
adb --help
查看 adb 帮助文档, 命令记不清楚的时候可以使用
Hello Appium
快速体验
需求
使用自动化方式, 打开 "设置" 应用程序
步骤
1. 按顺序打开 adb服务, 启动模拟器, 启动appium服务
2. 新建一个python项目
3. 新建一个 .py 文件
4. 在 py 文件中放置启动代码
备注
在步骤4 中, 这段代码实际上配置了一些启动应用程序的相关参数, 以后的其他项目也需要使用, 只是可能有些参数值不同, 为了方便, 我们以后会将这段代码称之为 "前置代码"
参数详解
小结
环境搭建
重点是自动化环境分析过程
adb调试工具
常用命令
获取包名和界面名?
文件传输?
获取app启动时间?
获取手机日志?
ddms?
安装和卸载?
其他命令?
第一个自动化脚本
要理解各个参数的含义
Appium API
基础操作API
总体介绍
内容
使用 appium 在脚本内启动其他的 app
使用 appium 获取包名和界面名
使用 appium 关闭 app 和驱动对象
使用 appium 安装卸载 app 以及判断app是否已安装
使用 appium 将应用置于后台
前置代码
在脚本内启动其他app
应用场景
1. 需要启动另一个app时
2. 需要模拟中断的状态时 (交叉事件)
命令
driver.start_activity("要启动的程序包的包名", "要打开的页面")
示例
需求
在 "设置" 中打开 "浏览器"
步骤
1. 获取浏览器的包名和启动名 com.android.browser
.BrowserActivity
2. 调用 start_activity 的方法, 打开浏览器应用
代码
获取包名和界面名
应用场景
用于支付场景是否跳转成功的断言
属性
# 获取包名
driver.current_package
# 获取界面名
driver.current_activity
示例
需求
打开"设置", 获取包名和界面名
步骤
1. 打开 "设置"
2. 调用属性去获取即可
代码
扩展
appium和adb都可以获取包名和界面名, 有什么区别?
区别
1 使用阶段不同
adb方式, 在测试脚本执行之前使用
appium方式, 在测试脚本开始编写之后
2 用途不同
通过adb方式获取, 是用于把获取结果放到前置代码中, 可以用于启动app
通过appium方式, 用于校验
关闭app和驱动对象
应用场景
释放资源
app不同了, 又想保留驱动对象, 可以关闭当前的app
driver用完了, 每次程序退出时应该关闭
命令
# 关闭当前app应用
driver.close_app()
# 关闭驱动对象
driver.quit()
对比记忆web自动化的 driver.close() 和 driver.quit()
示例
需求
执行前置代码后, 关闭"设置", 再关闭driver
步骤
1. 执行前置代码
2. 关闭设置应用
3. 关闭driver
代码
安装卸载以及判断是否安装
应用场景
命令
# 判断app是否已经安装
driver.is_app_installed("要判断的应用的程序的包名")
返回值: 布尔类型 , True 代表已安装, False 代表未安装
# 卸载app
driver.remove_app("要卸载的app的包名")
# 安装app
driver.install_app("安装包在pc的路径")
示例
需求
包名: cn.goapk.market
1. 判断"安智市场"是否已经安装
2. 如果已经安装, 则卸载
3. 如果未安装, 则安装
代码
将应用置于后台
应用场景
金融类/银行类的app的安全策略, 需要模拟将应用置于后台
命令
# 把当前app置于后台
driver.background_app(n秒)
示例
需求
把"设置" 置于后台5秒
代码
UIAutomatorviewer的使用
简介
用来扫描和分析 Android 应用程序 UI 控件的工具
路径
在SDK下的 tools 目录下
uiautomatorviewer.bat
示例
使用 UIAutomatorviewer 工具获取 "设置" 中, 放大镜图标的元素特征
步骤
1. adb服务和移动端已经联通
adb devices 能查到设备
2. 打开 ui...工具
3. 进入移动端的"设置"
4. 在 ui... 工具中, 点击左上角第二个小图标
5. 单击 ui... 工具中的界面上的放大镜图标
6. ui... 工具右下角的 Node Detail 中就可以看到元素的特征
元素定位API
总体介绍
什么样的元素能定位到???
对比
Selenium
页面包含的元素都可以进行定位, 包括视野里没有的
Appium
只能定位视野里存在的元素
定位一个元素
方法
id
driver.find_element_by_id("元素的resource-id属性值")
# 返回值: 定位到的这个元素
class
driver.find_element_by_class_name("元素的class属性值")
# 返回值: 定位到的这个元素
xpath
driver.find_element_by_xpath("xpath表达式")
# 返回值: 定位到的这个元素
如:
//*[@id = '元素的resource-id属性值']
//*[contains(@attribute, 'x')]
示例
通过 id 的形式, 定位 "放大镜" 按钮, 并点击
通过 class 的形式, 定位 "输入框", 输入 hello
通过 xpath 的形式, 定位 "返回" 按钮, 并点击
定位一组元素
方法
id
driver.find_elements_by_id("元素的resource-id属性值")
# 返回值: 列表, 定位到的所有符合条件的元素
class
driver.find_elements_by_class_name("元素的class属性值")
# 返回值: 列表, 定位到的所有符合条件的元素
xpath
driver.find_elements_by_xpath("xpath表达式")
# 返回值: 列表, 定位到的所有符合条件的元素
示例
定位元素的注意点
示例
使用 find_element_by_xxx 或者 find_elements_by_xxx 的方法, 分别传入一个没有的 特征, 会是什么结果
如, driver.find_element_by_id("xxx")
driver.find_elements_by_id("xxx")
小结
使用 find_element_by_xx 的方法, 如果定位失败, 会报 NoSuchElementException 的错误
使用 find_elements_by_xx 的方法, 如果定位失败, 不会报错, 会返回一个空列表
元素等待
总体介绍
概念
定位页面元素时, 如果未找到, 在指定时间内一直等待的过程
分类
1. 隐式等待
2. 显式等待
应用场景
网络速度慢
服务器处理请求速度慢
硬件配置原因
隐式等待
方法
# 隐式等待, 针对定位所有元素设置同一个超时时长会用到
driver.implicitly_wait(timeout)
# 参数: timeout 表示超时时间, 单位是 秒
示例
显式等待
方法
# 显式等待, 为定位不同的元素设置不同的超时时间
wait = WebDriverWait(driver, timeout, poll_frequency=0.5)
# 参数:
# driver: 驱动对象
# timeout: 超时时长, 单位, 秒
# poll_frequency: 查找时间间隔, 默认为 0.5 秒
wait.until(method)
# 参数:
# method: lambda 查找元素的表达式
# 返回值: 定位到的元素
示例
区别
使用方法
显示等待的方法封装在 WebDriverWait 类中, 而隐式等待则直接通过 driver 实例化对象调用
作用域
隐式等待全局有效, 显式等待为单个元素有效
关于 sleep
sleep 是固定死一个时间, 不是不行, 是不推荐
元素等待可以让元素出来的第一时间进行操作, sleep 可能造成浪费
元素操作API
总体介绍
分类
1. 操作: 点击, 输入和清空
2. 获取: 元素的文本内容, 位置, 大小, 根据属性名获取属性值
点击元素
方法
# 对 element 元素进行点击操作
element.click()
示例
输入和清空输入框
方法
# 对 element 输入框进行清空的操作
element.clear()
# 对 element 输入框进行输入的操作
element.send_keys("要输入的内容")
示例
获取元素的文本内容
应用场景
有些应用界面中, 很多元素 resource-id 和 class 特征都一样, 此时可能不知道定位到了哪一个元素, 需要获取元素的 text 属性值来帮助校验
属性
# 获取 element 元素的文本内容
element.text
# 返回值: 元素的文本内容
获取元素的位置
属性
# 获取 element 的位置
element.location
# 返回值: 字典 , x 为元素的 x 坐标, y 为元素的 y 坐标
示例
获取元素的大小
属性
# 获取 element 的大小
element.size
# 返回值: 字典 , width 为元素的 宽度, height 为元素的 高度
示例
获取元素的属性值
方法
element.get_attribute("要获取的属性名")
# 返回值: 根据属性名得到的属性值
示例
滑动和拖拽事件
总体介绍
应用场景
用于定位: 有些按钮是需要滑动几次屏幕后才出现
用于业务功能: 比如有些应用存在引导页的功能, 需要翻页才能进入主界面
内容
swipe
scroll
drag_and_drop
swipe滑动方法
方法
# 从一个坐标位置滑动到另一个坐标位置, 只能是两个点之间的滑动
driver.swipe(起点的x坐标, 起点的y坐标, 终点的x坐标, 终点的y坐标, duration=None)
示例
sroll滑动方法
方法
# 从一个元素滑动到另一个元素, 直到页面自动停止
driver.scroll(开始的元素, 结束的元素, duration=None)
示例
drag_and_drop拖拽方法
方法
# 从一个元素滑动到另一个元素, 第二个元素替代第一个元素原本在屏幕上的位置
driver.drag_and_drop(开始的元素, 结束的元素)
示例
滑动和拖拽方法的选择
滑动和拖拽无非就是考虑是否有"惯性", 以及传递的参数是 元素 还是 坐标
传入元素
sroll
有惯性
drag_and_drop
无惯性
传入坐标
swipe
把duration设置一个较大的值, 接近于无惯性
把duration设置一个较小的值, 有惯性
高级手势TouchAction
总体介绍
内容
轻敲, 按下和抬起, 等待, 长按, 手指移动
应用场景
如, 手势解锁
使用步骤
1. 创建 TouchAction 对象
2. 通过对象调用想执行的手势
3. 通过 perform() 执行动作
注意点
所有手势都要通过执行 perform() 才能运行
轻敲操作
方法
TouchAction(driver).tap(element=None, x=None, y=None, count=1).perform()
示例
按下和抬起操作
方法
TouchAction(driver).press(el=None, x=None, y=None).release().perform()
示例
等待操作
方法
TouchAction(driver).wait(ms=0).perform()
示例
长按操作
方法
TouchAction(driver).long_press(el=None, x=None, y=None, duration=1000).perform()
示例
移动操作
方法
TouchAction(driver).move_to(el=None, x=None, y=None).perform()
示例
提示
屏幕解锁图案界面的界面名是 : .ChooseLockPattern
手机操作API
总体介绍
内容
获取手机分辨率
获取手机截图
获取和设置网络状态
发送键到设备
打开和关闭手机通知栏
获取手机分辨率
方法
driver.get_window_size()
示例
作业
# 随堂作业: 按照坐标, 从 屏幕 y 轴 4分之3 滑动到 4分之1 , 要求横坐标是屏幕的 2分之一
获取手机截图
方法
driver.get_screenshot_as_file("路径+文件名")
示例
获取和设置网络状态
属性
driver.network_connection
方法
driver.set_network_connection(connectionType)
示例
发送键到设备
方法
driver.press_keycode(keycode)
示例
打开和关闭手机通知栏
方法
# 打开手机通知栏
driver.open_notifications()
示例
小结
pytest
基本使用
pytest vs unittest
概念
对比
pytest特点
1. 非常容易上手, 入门简单, 文档丰富
2. 支持简单的单元测试和复杂的功能测试
3. 支持运行由 unittest 编写的测试用例
4. 支持测试用例失败重试
5. 支持参数化
6. 执行测试过程中可以将某些测试用例跳过
7.支持对某些预期失败的用例做标记
安装和运行方式
安装
校验
运行
前置和后置方法
函数级的方法setup和teardown
概念
类级的方法setup_class和teardown_class
概念
在什么位置放置驱动对象的获取和关闭???
如果测试用例比较少, 页面层级不多, 可以放在类级setup_class和 teardown_class中
如果测试用例比较多, 页面层级较深, 可以放在函数级setup和teardown中
配置文件
pytest.ini
常用插件
测试报告
安装
使用命令 pip install pytest-html
推荐 pip install pytest-html==1.21.1
使用
在配置文件中的命令行参数增加 --html=用户路径/report.html
示例
控制函数执行顺序
安装
使用命令 pip install pytest-ordering
使用
标记于测试函数, @pytest.mark.run(order=x), x 代表执行顺序的数字
示例
失败重试
应用场景
网络不稳定时使用
安装
使用命令 pip install pytest-rerunfailures 进行安装
使用
在配置文件中的命令行参数增加 --reruns n, n 是表示失败重试的次数
示例
高级用法
跳过测试函数
方法
@pytest.mark.skipif(condition, reason=None)
使用方式
在需要跳过的测试函数上, 加上装饰器 @pytest.mark.skipif(condition, reason="xxx")
示例
预期失败
方法
@pytest.mark.xfail(condition, reason=None)
使用方式
在需要标记预期失败的测试函数上, 加上装饰器 @pytest.mark.xfail(condition, reason="xxx")
示例
数据参数化
总体介绍
方法
@pytest.mark.parametrize("参数名", 一般是列表参数值)
示例
单一参数
多个参数
推荐用法
fixture
总体介绍
应用场景
用 fixture 装饰器来标记固定的工厂函数, 在其他函数, 类调用它的时候会被激活并优先执行, 通常用于完成预置处理和重复操作
使用步骤
1. 标记
某个函数作为工厂, (如: 标记一个函数名为 before 的函数为工厂函数)
2. 引用
指定一个函数, 引用这个工厂(如: 制定一个函数名为 test_a 的函数去引用 before)
备注
效果: 如 test_a 引用了 工厂函数before, 那么 会先执行 before 再执行 test_a
标记方式
# 在函数上使用装饰器 @pytest.fixture() 来标记工厂函数
# 参数:
# 略
@pytest.fixture()
def before(self):
pass
引用方式
通过参数引用
示例
通过装饰器来引用
示例
扩展
比较一下工厂函数和setup
参数
默认运行
autouse
作用域
scope
参数化
params
返回值
小结
重点内容
常用插件
测试报告
控制函数执行顺序
失败重试
高级用法
跳过测试函数
预期失败
数据参数化
fixture 了解即可
PO
PO模式简介
封装过程
工作中, 不需要大家去一步一步封装成PO模式的代码, 只需要一步到位即可
总结
综合案例
扩展
yaml
总体介绍
概念
yaml 和 json 一样, 是一种数据格式
yaml 是一种所有编程语言都可用的友好的数据序列化标准. 在 python 中, 可以表达字典/列表/其他基本数据类型
应用场景
1. 通用场景, 用于数据序列化
2. 在自动化测试中, 用于数据驱动
数据驱动指的就是测试数据的参数化, 且测试数据和代码分离
[扩展]序列化和反序列化
背景
计算机硬件中, 和数据存储有关的硬件
内存
硬盘
其中, 内存的读写速度要比硬盘快得多
内存用于做临时计算
硬盘用于持久化保存计算结果
概念
序列化
将内存中的对象 (编程语言可以识别的数据类型) 写入到硬盘的过程, 即文件写操作
反序列化
将硬盘中的数据 (恢复为可运行的数据格式) 读取到内存中的过程, 即文件读操作
快速体验
语法规则
大小写敏感
使用缩进表示层级关系
缩进时不允许使用Tab键, 只允许使用空格
缩进的空格数据不重要, 只要相同层级的元素左对齐即可
需求
读 yaml 格式的文件
name: "xiaoming"
age: "18"
数据表示
字典和列表
字典和列表相互嵌套
练习
基本数据类型
在python中的读写
读取yaml文件
写入yaml文件
数据驱动
项目准备
打开通讯录, 添加联系人
需求
@pytest.mark.parametrize("args", [{"name": "zhangsan", "phone": "18888888888"}, {"name": "lisi", "phone": "13333333333"}, {"name": "wangwu", "phone": "17777777777"}]) 改写为 yaml 这种格式
扩展
[面试]appium + python + pytest + yaml + PO 整个的自动化框架的架构
yaml数据和脚本的对应关系
笔记中的示例的层级结构
登录模块 test_login.py
脚本 def test_login
zhangsan, zhangsan123
lisi, lisi123
wangwu, wangwu123
注册模块 test_sign_up.py
脚本 def test_username_sign_up
zhangsan, zhangsan321
lisi, lisi321
脚本 def test_phone_sign_up
13333333333, 123000
18888888888, 321000
yaml数据编写
yaml数据解析
调整测试脚本
增加断言
大标题
resource-id
com.android.contacts:id/large_title
allure
总体介绍
allure是一个独立的报告插件, 生成美观易读的报告, 目前支持 java, python, ruby, php, C#等
帮助文档
步骤
最终我们会生成一个 html 格式的报告, 中间需要操作两步
1. 生成 xml
前提: 安装
pip install pytest-allure-adaptor
2. 将 xml 转成 html
前提: 安装
1. 下载 allure-2.6.0.zip
2. 解压缩到一个目录
3. 将解压目录下的 bin 目录配置到环境变量 path 中
4. 在命令行输入 allure 命令, 如果提示是有这个命令, 说明成功
基本使用
生成 xml 步骤
1. 将 pytest.ini 中的命令行参数加上 --alluredir report
2. 正常运行 pytest 即可
3. 程序运行结束后, 会在对应的 report 目录下生成一个 xml 文件
生成 html 步骤
1. 进入report 上级目录, 执行命令
allure generate report/ -o report/html --clean
2. report 目录下会生成 html 文件夹, 文件夹下会有一个 index.html , 用浏览器打开即可
参数和命令详解
与pytest结合
项目准备
使用 PO 模式 + pytest 框架来制作程序, 实现"设置"应用中, 搜索 "hello1" 和 "xiaoming"
项目的实现过程不作为重点, 能理解即可
添加测试步骤
在 page 中的所有方法上加上 @allure.step(title="测试步骤001")
添加测试描述
添加优先级
toast
总体介绍
概念
toast 是 android 系统中的一种消息框类型
应用场景
获取 toast 内容, 用于验证交互逻辑
快速体验
需求
打开"文件管理器", 点击 "返回" 按钮, 获取toast 提示内容
环境安装
1. 安装 node.js
2. cnpm
3. 安装 appium-uiautomator2-driver
获取toast内容
1. 前置代码添加
desired_caps["automationName"] = "Uiautomator2"
2. 使用 xpath 找 text 即可
WebView
总体介绍
webview 是一个基于webkit引擎, 展示html页面控件
查看webview元素的方式
1. UIAutomatorviewer 查看
一般行不通, 万一能查看到元素, 那是人品很好
2. 通过chrome直连手机查看
1. 确保 adb devices 可以发现设备
2. 移动端打开要查看的webview页面
3. 在 chrome 中输入 chrome://inpect 地址, 并点击 inspect
4. 选中要查看的元素即可
3. [推荐]通过 chrome 浏览器查看手机的页面地址
1. 确保 adb devices 可以发现设备
2. 移动端打开要查看的webview页面
3. 复制移动端的地址, 在 chrome 中打开
4. 选中要查看的元素即可
实现webview自动化
关于没有对应的chromedriver的问题
1.下载对应的 chromedriver
2. 启动appium 时加载 chromedriver
Monkey
总体介绍
monkey是什么
monkey 就是猴子, monkey 测试, 就像一只猴子在设备上乱敲乱点
monkey用来做什么
monkey 主要用于android的压力/稳定性测试, 目的就是为了测试 app 是否会崩溃 (crash)
命令参数
日志分析
正常情况
如果 monkey 测试顺利执行完成, 在log最后, 会打印出当前执行事件的次数和所花费的时间
异常情况
monkey测试出现错误, 应该好好分析
1. 崩溃问题: 在日志中搜索 "Exception"
2. 程序无响应问题: 在日志中搜索 "ANR"
可能仅仅是因为程序卡顿
unittest
组成
TestCase(测试用例)
测试用例是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown))
Test fixture(测试固件)
测试代码的运行环境,指测试准备前和执行后要做的工作,包括setUp()和tearDown();
TestSuit(测试集)
多个测试用例集合在一起
TestLoader(加载用例)
用来加载Testcase到TestSuite中
TextTestRunner(执行用例)/HTMLTestRunnerNew(推荐使用,生成HTML网页版测试报告)
运行原理
TestSuite对多个TestCase的整合到一起,TestLoader: 加载TestCase实例(即测试用例)到TestSuite实例中,TextTestRunner:测试用例运行类,实例化出此类的一个对象,然后把TestSuite实例做为参与传进去,就可以运行测试了
测试用例
1.测试类继承unittest.TestCase
2.用例名称前必须用test_开头,否则不识别!
3.断言
需要判断用例是Pass还是Fail,可以用unittest.TestCase模块的:断言
如果测试失败则显示为F,测试通过为.
常用断言
assertEqual(a,b,msg='None') 判断a,b是否相等,不相等时,抛出msg;13;assertTure(x,msg='None') 判断x表达式是否为真,表达式为假时,抛出msg;13;assertIn(a,b,msg='None') 判断a是否在b里面,a不在b里面时,抛出msg;13;assertIsNone(x,msg='None') 判断x是否为空,x不为空时,抛出msg。13;
4.运行执行
unittest.main()
执行条件
:执行的时候会自动搜索模块中以“test”命名开头的测试方法。
执行默认顺序
根据ASCII码的顺序加载测试用例。
数字与字母的顺序为:0-9,A-Z,a-z。
所以A开头的测试用例方法会优先执行,以a开头会后执行。
if __name__ == '__main__':13; unittest.main(verbosity=2)
外部模块调用的时候不执行我们的调试代码
既可以让“模块”文件运行,也可以被其他模块引入,而且不会执行函数2次
测试固件
前置和后置
setUp()
初始化环境,连接数据库、初始化浏览器等。
tearDown()
清洗环境(执行每条用例之后,都要执行tearDown函数下面的代码,每次都要执行)
setUpClass()
tearDownClass()
测试集(测试套件)
unittest.TestSuite()
使用场景
只想执行其中部分,可以使用TestSuit()来收集测试用例
使用
创建测试集
suite=unittest.TestSuit()
给测试集合添加测试用例
suite.addTest(测试用例的类('用例名称1'))
addTests([,,]):添加多个测试用例
案例
suite=unittest.TestSuit()13;suite.addTest(测试用例的类('用例名称1')) #用例名称用字符串的形式传入13;suite.addTest(测试用例的类('用例名称2'))
unittest.defaultTestLoader()
使用场景
想一次性加载某个模块下所有测试用例
使用
通过该类下面的discover()方法可根据测试目录匹配查找测试用例文件(test*.py),并将查找到的测试用例组装到测试套件,因此可以直接通过run()方法执行discover
discover = unittest.defaultTestLoader.discover(case_path, pattern='test_*.py')
discover
case_dir:这个是待执行用例的目录。
子主题 1
pattern:这个是匹配脚本名称的规则,test*.py意思是匹配test开头的所有脚本
top_level_dir:这个是顶层目录的名称,一般默认等于None就行了
案例
discover = unittest.defaultTestLoader.discover(case_path,13; pattern='test*.py',13; top_level_dir=None)13;
执行套件
TextTestRunner
unittest框架的TextTextRunner()类,配合TestSuite()、defaultTestLoader()类一起使用,通过TextTextRunner类下面的run()方法来运行套件所组装的测试用例,入参为suite测试套件。
runner = unittest.TextTestRunner()13; runner.run(discover)
测试报告
HTMLTestRunner
准备
1.需要下载包
http://tungwaiyip.info/software/HTMLTestRunner.html
2.目录
下载后手动拖到python安装文件的Lib目录下
参数
title:测试报告的主题
stream:测试报告写入文件的存储区域
description:测试报告的描述
案例
report_abspath = os.path.join(report_path, 'result.html')13; fp = open(report_abspath, 'wb')13; runner = HTMLTestRunner.HTMLTestRunner(stream=fp,13; title=u'自动化测试报告,测试结果如下:',13; description=u'用例执行情况:')13;13; # 调用add_case函数返回值13; runner.run(all_case())13;
装饰器
@unittest.skip()
跳过部分测试用例
分支主题
@skip(reason)装饰器:无条件跳过装饰的测试,并说明跳过测试的原因。13;13;@skipIf(condition,reason)装饰器:条件为真时,跳过装饰的测试,并说明跳过测试的原因。13;13;@skipUnless(condition,reason)装饰器:条件为假时,跳过装饰的测试,并说明跳过测试的原因。13;13;@ expectedFailure()测试标记为失败。
@classmethod
配置setUpClass(cls)和tearDownClass(cls): 一起使用
数据驱动(ddt)
使用场景
针对某些功能相同,但是输入的参数数据不同时,可以使用数据驱动设计的模式
安装
pip install ddt
使用
装饰类
@ddt.ddt
继承TestCase的类。
装饰方法
@ddt.data()
装饰测试方法,装饰器的参数就是测试数据:@ddt.data(*testData)
testData可以是数组或者元祖
@ddt.file_data
参数是文件名。文件可以是json或者yaml类型。
如果文件是以“.yml”或者'.yaml'结尾,ddt会作为yaml类型处理,其他文件都会作为json文件处理。
@ddt.unpack
分解list或者tuple
分解tuple
@data((1,2),(4,5)) #元组13; @unpack #分解13; def test_one(self,value1,value2):13; print(f'the @data number is :{value1,value2}')
分解字典
@data({'value1':1,'value2':2},{'value1':3,'value2':4}) #字典13; @unpack13; def test_one(self,value1,value2):13; print(f'the @data number is :{value1,value2}')
元素定位
xpath元素定位
根据元素自身特征定位
属性完全匹配
//标签(可以用*表示)[@属性=“属性值”]
其他属性。。
//*[@data-log_code='bid=3213225']
class
//*[@class='topbar-cart']
id
//input[@id='search']
//标签(可以用*表示)[@属性1=“属性值”][@属性2=“属性值”]
//*[@data-log_code='bid=3213225'][@class='item ']
//标签(可以用*表示)[@属性1=“属性值” and @属性2=“属性值” ]
//*[@data-log_code='bid=3213225' and @class='item ']
属性值部分匹配
//*[contains[@属性,'部分属性值']]
//*[contains(@class,'home-channel-list')]
根据元素层级关系定位
上下级关系
后代关系(可以跨级)
祖先//后代
//*[@id='J_categoryList']//li
父子关系(直接上下级)
父元素/子元素
//*[@id='J_categoryList']/li
指定子元素
父元素/子元素[n]
n从1开始表示正数
last()表示倒数第一
同级关系
哥哥
弟弟/preceding-sibling::哥哥们
弟弟/preceding-sibling::哥哥[n]
n从1开始表示正数
last()表示倒数第一
弟弟
哥哥/following-sibling::弟弟[n]
n从1开始表示正数
last()表示倒数第一
哥哥/following-sibling::弟弟们
验证表达式
用控制台的搜索框(ctrl+f开启)
web自动化
web自动化入门
自动化
概念
由机器设备代替人工自动完成指定目标的过程
优点
减少人工劳动力
提高工作效率
产品规格统一标准
规模化
安全
自动化测试
概念
用程序代替人工去执行测试的过程
应用场景
解决-回归测试
已实现的功能需要回归
已解决的bug需要回归
解决-压力测试
如, 使用 jmeter做接口自动化
解决-兼容性测试
如, 在不同浏览器上做兼容性测试
解决-操作重复的问题
正确认识
优点
较少的时间内运行更多的测试用例
自动化脚本可重复运行
减少人为的错误
克服手工测试的局限性
误区
自动化测试可以完全代替手工测试
自动化测试一定比手工测试厉害
自动化测试可以发现更多bug
自动化测试适用于所有功能
分类
接口-自动化测试
web-自动化测试(本阶段学习)
移动-自动化测试
单元-自动化测试
web自动化测试
概念
用程序代替人工去执行web测试的过程
什么样的项目适合做web自动化?
需求变动不频繁
项目周期较长
项目需要回归测试
web自动化应该什么时候开始做?
手工测试结束后
selenium
web自动化工具简介
主流工具
QTP
一个收费的自动化测试工具, 支持web/桌面自动化测试
selenium
一个开源的web自动化测试工具, 主要做功能测试
robot framework
一个基于python的可扩展的关键字驱动的自动化测试框架
selenium特点
开源
跨平台
支持多种浏览器
支持多种语言
成熟稳定
功能强大
环境搭建
搭建步骤
前提: 基于python搭建
1. python 开发环境
2. 安装 selenium 包
3. 安装 浏览器
4. 安装 浏览器驱动
安装selenium包
安装
校验
卸载
安装浏览器驱动
前提: 安装了浏览器
https://www.chromedownloads.net/
安装步骤
1.下载浏览器驱动
https://npm.taobao.org/mirrors/chromedriver/
2.把驱动文件所在的目录添加到环境变量Path中
python的安装目录应该已经添加到了环境变量中
只需要把驱动程序放在 python的根目录下
入门示例
需求
通过程序, 启动浏览器, 并打开百度首页, 暂停3秒, 关闭浏览器
实现
步骤
示例代码
小结
自动化/自动化测试/web自动化测试的概念是什么?
自动化测试的应用场景有哪些?
web自动化测试的应用场景有哪些?
什么样的项目适合做web自动化?
web自动化应该什么时候开始做?
编程题
需求: 通过程序启动浏览器, 打开京东首页, 暂停5s, 关闭浏览器
Selenium-API
元素定位基础
为什么进行元素定位
如何进行元素定位
浏览器开发者工具
概念
就是给专业的web应用和网站开发人员使用的工具
作用
定位元素, 查看元素信息
使用
需求: 使用浏览器开发者工具, 查看百度的输入框的相关信息
步骤
安装
无需安装, 浏览器自带了
启动
快捷键一般都是F12
使用方式
方式1
在要查看的元素上点击右键选择"检查"(Chrome) 或者 "查看元素"(Firefox)
方式2
先打开浏览器开发者工具, 点击选择元素的图标, 移动鼠标到要查看的元素, 然后点击
元素定位方式
总体介绍
web案例
受限于网络速度, 我们案例采用本地的 html 页面来演示
这样可以提高学习效率和脚本执行速度
八种定位方式
Selenium 提供了八种定位元素的方式
1. id
2. name
3. class_name
4. tag_name
5. link_text
6. partial_link_text
7. XPath
8. CSS
id定位
说明: 就是通过元素的id属性来定位元素, html规定 id 属性在整个 html 文档中必须唯一的
前提: 元素有id属性
方法
element = driver.find_element_by_id(id)
案例
需求
打开 注册A.html 页面, 完成以下操作
1. 使用id定位, 输入用户名: admin
2. 使用id定位, 输入密码: 123456
3. 5s后关闭浏览器
实现
name定位
说明: 就是通过元素的name属性来定位元素, 在html文档中 name 属性值是可以重复的
前提: 元素有name属性
方法
element = driver.find_element_by_name(name)
案例
需求
打开 注册A.html 页面, 完成以下操作
1. 使用name定位, 输入用户名: admin
2. 使用name定位, 输入密码: 123456
3. 5s后关闭浏览器
实现
class_name定位
说明: 就是通过元素的class属性值来定位元素, html 通过使用class来定义元素的样式
前提: 元素有class属性
注意: 如果class有多个属性值, 只能使用其中一个
方法
element = driver.find_element_by_class_name(class_name)
案例
需求
打开 注册A.html 页面, 完成以下操作
1. 使用class_name定位, 输入电话号码: 13111111111
2. 使用class_name定位, 输入邮箱: 123456@qq.com
3. 5s后关闭浏览器
实现
tag_name定位
说明: tag_name定位就是通过标签名来定位
注意: html本质就是由不同的tag组成, 每一种标签一般在页面中会存在多个, 所以不方便进行精准定位, 一般很少使用
方法
element = driver.find_element_by_tag_name(tag_name)
# 如果存在多个相同的标签, 则会返回符合条件的第一个标签
# 如何获取第二个元素? 后面会讲
link_text定位
说明: 是专门用来定位超链接元素(<a>内容...</a>), 并且是通过超链接的文本内容来定位元素
方法
element = driver.find_element_by_link_text(link_text)
# link_text: 超链接的全部文本内容
案例
需求
打开 注册A.html 页面, 完成以下操作
1. 使用link_name定位(访问 新浪 网站)超链接, 并点击
2. 5s后关闭浏览器
实现
partial_link_text定位
说明: partial_link_text 定位是对 link_text 定位的补充, link_text 使用全部文本内容匹配元素, 而 partial_link_text 可以使用局部文本内容来匹配元素, 也可以使用全部文本内容匹配元素
方法
element = driver.find_element_by_partial_link_text(partial_link_text)
# partial_link_text: 可以传入a标签的局部文本
案例
需求
打开 注册A.html 页面, 完成以下操作
1. 使用partial_link_name定位(访问 新浪 网站)超链接, 并点击
2. 5s后关闭浏览器
实现
定位一组元素
方法
elements = driver.find_elements_by_xxx("xxxxxx")
作用:
1. 查找定位符合条件的所有元素
2. 返回值是一个列表
说明: 列表数据格式的读取需要指定下标(下标从0开始)
案例
需求
打开 注册A.html 页面, 完成以下操作
1. 使用 tag_name 定位密码输入框(第二个input标签), 并输入123456
2. 5秒后关闭浏览器
实现
元素定位-XPath/CSS
总体介绍
为什么要学习XPath/CSS
XPath定位
什么是XPath
概念
XPath就是XML Path, 它是一门在XML文档中查找元素信息的语言
HTML可以看做是XML的一种实现, 所以Selenium用户可以使用这种强大的语言在web应用中定位元素
XPath定位方式
总体介绍
四种定位方式
路径
元素属性
属性和逻辑结合
层级与属性结合
方法
element = driver.find_element_by_xpath(xpath)
路径
概念
绝对路径
从最外层元素到指定元素之间所有经过元素层级的路径
1 绝对路径以 /html 根节点开始, 使用 / 来分割元素层级
如: /html/body/div/fieldset/p[1]/input
2 绝对路径对页面结构要求比较严格, 不建议使用
相对路径
匹配任意层级的元素, 不限制元素的位置
1 相对路径 // 开始
2 格式: //input 或者 //*
练习
需求
打开 注册A.html 页面, 完成以下操作:
1.使用绝对路径定位用户名输入框, 并输入 admin
2.暂停 3s
3.使用相对路径定位密码输入框, 并输入 123
实现
利用元素属性
说明: 通过使用元素的属性信息来定位元素
格式: //input[@id='userA'] 或者 //*[@id='userA']
练习
属性与逻辑结合
说明: 解决元素之间存在相同属性值的问题
格式: //*[@name='xxx' and @class='yyy']
练习
层级与属性结合
说明: 如果通过元素自身的属性不方便直接定位该元素, 则可以先定位到其父元素, 然后再找到该元素
格式: //*[@id='p1']/input
练习
XPath扩展
说明:
不使用函数时:
//*[@id='xxx']
使用函数后
//*[text()='xxx'] 文本内容是 xxx 的元素
//*[contains(@attribute, 'xxx')] 属性中含有 xxx 值的元素
//*[starts-with(@attribute, 'xxx')] 属性以xxx开头的元素
CSS定位
什么是CSS
1.CSS 是一种语言, 它用来描述html元素的现实样式
2.在CSS中, 选择器是一种模式, 用于选择需要添加样式的元素
3.在Selenium中也可以使用这种选择器来定位元素
提示:
1.在Selenium中推荐使用CSS定位, 因为它比XPath定位速度快
2.CSS选择器语法非常强大, 在这里我们只学习在测试中常用的几个
CSS定位方式
总体介绍
常用定位方式
id选择器
class选择器
元素选择器
属性选择器
层级选择器
方法
element = driver.find_element_by_css_selector(css表达式)
id选择器
说明: 根据元素id属性来选择
格式: #id
例如: #userA (选择id属性值为userA的元素)
练习
class选择器
说明: 根据元素class属性来选择
格式: .class值
例如: .telA (选择class属性值为 telA的元素)
练习
元素选择器
说明: 根据元素的标签名选择
格式: 标签名
例如: input (选择input元素)
练习
属性选择器
说明: 根据元素的属性名和值来选择
格式: [attribute=value]
例如: [type='password'] (选择 type 属性值为 password 的元素)
练习
层级选择器
说明: 根据元素的父子关系来选择
格式1: element1>element2 通过element1来定位element2, 并且 element2 必须为 element1 的直接子元素
例如1: p[id='p1']>input (定位指定p元素下的直接子元素input)
格式2: element1 element2 通过element1来定位element2, 并且 element2 为 element1的后代元素
例如2: p[id='p1'] input (定位指定p元素下的后代元素 input)
练习
CSS扩展
input[type^='p'] type属性以p字母开头的元素
input[type$='d'] type属性以d字母结束的元素
input[type*='w'] type属性包含w字母的元素
练习
XPath和CSS对比
通过标签名定位
XPath
//input
CSS
input
通过id属性定位
XPath
//*[@id='userA']
CSS
#userA
通过class属性定位
XPath
//*[@class='telA']
CSS
.telA
通过其他属性定位
XPath
//*[starts-with(@type,'x')]
以x字母开头的type值的元素
//*[contains(@type, 'x')]
包含x字母的type值的元素
//*[text()='x']
文本内容为 x 的元素
CSS
[type^='x']
以x字母开头的type值的元素
[type*='x']
包含x字母的type值的元素
[type$='x']
以x字母结尾的type值的元素
元素定位总结
元素定位分类汇总
1. id, name, class_name: 元素属性定位
2. tag_name: 元素标签名定位
3. link_text, partial_link_text: 通过文本定位超链接
4. XPath: 通过路径定位元素
5. CSS: 使用CSS选择器定位
另一种写法
方法介绍
第一种
driver.find_element_by_xxx(xxx)
方法: driver.find_element(方式, 值)
备注:
1.需要2个参数, 第1个参数为定位的类型(由By提供), 第2个参数传入具体的值
2.如果要使用By, 需要导包
练习
区别
元素操作
应用的场景
需要让脚本模拟用户的点击操作
需要让脚本模拟用户输入一些内容
需要让脚本模拟用户去清空输入框的内容
方法
click() 点击元素
send_keys(value) 模拟输入
clear() 清除文本
案例
需求
打开注册A页面,完成以下操作
1.通过脚本执行输入用户名:admin;密码:123456;电话号码:18611111111;电子邮件:123@qq.com
2.间隔3秒,修改电话号码为:18600000000
3.间隔3秒,点击‘注册’按钮
4.间隔3秒,关闭浏览器
ps: 元素定位方法不限
浏览器操作
获取元素信息
应用场景
通过获取元素信息来确认定位到的元素是否正确
方法
属性
size
text
方法
get_attribute("xxx")
获取属性值, 参数为属性名
is_displayed()
is_enabled()
is_selected()
案例
需求
实现
鼠标操作
概述
什么是鼠标操作
点击, 右击, 双击, 悬停, 拖拽等
应用场景
现在web产品中存在丰富的鼠标交互方式, 作为一个web自动化测试框架, 需要应对这些鼠标操作的场景
常用方法
说明: 在Selenium中将鼠标操作的方法封装在 ActionChains 类中
实例化对象: action = ActionChains(driver)
方法:
1. context_click(element) 右击
2. double_click(element) 双击
3. move_to_element(element) 悬停
4. drag_and_drop(source, target) 拖拽
5. perform() 执行
为了更好的学习其他的方法, 我们先学习 perform() 执行方法, 因为ActionChains所有的方法都需要执行才能生效
调用上的小区别:
element.click()
context_click(element)
鼠标执行 perform()
说明: 在 ActionChains 类中所有提供的鼠标事件方法, 在调用的时候, 所有行为都存储在 ActionChains 对象中, 而 perform() 方法就是真正去执行所有的鼠标事件
强调: 必须调用 perform() 方法才能执行鼠标事件
鼠标右击 context_click()
说明: 对于点击鼠标右键, 如果弹出的是浏览器的默认菜单, Selenium并没有提供操作菜单的方法
如果是自定义的右键菜单, 则可以通过元素定位来操作菜单中的选项
练习
# 需求: 打开A页面, 在用户名文本框上点击鼠标右键
实现
鼠标双击 double_click()
说明: 模拟鼠标双击左键的操作
练习
需求: 打开A页面, 输入用户名 admin, 暂停3s, 双击鼠标左键(选中admin)
实现
鼠标悬停 move_to_element()
说明: 模拟鼠标悬停在指定元素上
练习
需求: 打开A页面, 模拟鼠标悬停在 注册 按钮上
实现
鼠标拖动 drag_and_drop()
说明: 模拟鼠标拖动动作, 选定拖动源元素释放到目标元素
关键点分析
1. 源元素 source = driver.find_element_by_xxx("xxx")
2. 目标元素 target = driver.find_element_by_xxx("xxx")
3. 调用方法 action.drag_and_drop(source, target).perform()
练习
需求: 打开 drag.html 页面, 把红色方框拖动到蓝色方框上
实现
键盘操作
应用场景
1. 模拟键盘上一些按键或者组合键的输入, 如: ctrl + c , ctrl + v
2. Selenium中把键盘的按键都封装在 Keys 类中
常用操作
导包
1. send_keys(Keys.BACK_SPACE) 删除键(Backspace)
2. send_keys(Keys.SPACE) 空格键(Space)
3. send_keys(Keys.TAB) 制表键(Tab)
4. send_keys(Keys.ESCAPE) 回退键(ESC)
5. send_keys(Keys.ENTER) 回车键(Enter)
6. send_keys(Keys.CONTROL, 'a') 全选(Ctrl + A)
7. send_keys(Keys.CONTROL, 'c') 复制(Ctrl + C)
提示: 以上方法很多, 不会逐一讲解, 因为调用方法都一样
案例
需求
打开 A 页面, 完成以下操作
1. 输入用户名 admin1, 暂停2s, 删除1
2. 全选用户名 admin 暂停2s
3. 复制用户名 admin 暂停2s
4. 粘贴到电话输入框
实现
元素等待
概念
定位元素时, 如果未找到, 在指定时间内一直等待的过程
分类
隐式等待
显式等待
应用场景
由于一些原因, 我们想找元素没有立刻出来, 此时如果直接定位会报错
1. 网络速度慢
2. 服务器处理请求速度慢
3. 硬件配置原因
隐式等待
方法
driver.implicitly_wait(timeout)
# 隐式等待为全局设置 (只需要设置1次, 就会作用于所有元素)
# 参数:
# timeout: 超时时长, 单位: 秒
案例
显式等待
说明
在Selenium中把显式等待的相关方法封装在 WebDriverWait 类中
方法
# 显式等待, 为定位不同的元素的超时时间设置不同的值
1.导包
2.WebDriverWait(driver, timeout, poll_frequency=0.5)
1.driver: 浏览器驱动对象
2.timeout: 超时时长, 单位: 秒
3.poll_frequency: 检测的间隔时间, 默认为0.5s
3.调用 until(method)
1.method: 函数名称, 该函数用来实现元素定位
2.一般使用匿名来实现: lambda x: x.find_element_by_xxx("xxx")
如:element = WebDriverWait(driver,10,1).until(lambda x: x.find_element_by_xxx("xxx"))
案例
隐式和显式区别
1. 作用域: 隐式等待为全局有效, 显式等待为单个元素有效
2. 使用方法: 隐式等待直接通过驱动对象调用, 而显式等待方法封装在 WebDriverWait 类中
3. 达到最大超时时长后抛出异常不同: 隐式等待为 NoSuchElementException, 显式等待为 TimeoutException
下拉框/弹出框/滚动条操作
下拉框
方法1
传统的方法
方法2
Select类
弹出框
分类
alert
警告框
confirm
确认框
prompt
提示框
错误示范
方法
1. 获取弹出框对象
2. 调用方法操作弹出框
具体方法说明
说明: Selenium中对弹出框的处理, 有专用的方法, 且处理的方法都一样(alert/confirm/prompt)
1.获取弹出框对象
alert = driver.switch_to.alert
2.调用
alert.text 返回alert/confirm/prompt文字信息
alert.accept() 接受对话框选项(确认)
alert.dismiss() 取消对话框选项(取消)
正确示范
滚动条
应用场景
在html中, 由于前端技术更新, 很多网站内容都是动态加载的
如, 页面注册同意条款, 需要滚动条到最底层才能点击"同意"
实现方式
Selenium中没有提供滚动条的操作
Selenium提供了操作JavaScript的方法
通过JS来操作滚动条
说明
说明: Selenium中没有提供滚动条的操作方法, 但是它提供了执行 JS 的方法, 所有我们可以通过 JS脚本来操作滚动条
1. 设置 JS 脚本控制滚动条
js = "window.scrollTO(0,1000)"
(0:左边距, 1000:上边距 单位:像素(px))
2. Selenium 调用执行 JS 脚本的方法
driver.execute_script(js)
案例
frame切换
frame概念
html页面中的一种框架, 主要作用是在当前页面指定区域显示另一个页面元素:
frame : html页面中的一种框架, 主要作用是在当前页面指定区域显示另一个页面元素
形式一:
<frameset cols="25%,75%">
<frame src="a.html">
<frame src="b.html">
</frameset>
形式二:
<iframe name="iframe_a" src="demo.html" width="200" height="200"></iframe>
错误示范
方法
在Selenium中封装了如何切换frame框架的方法
步骤
1.切换到指定的frame
2.恢复默认页面
正确代码
多窗口切换
概念
方法
实现
窗口截图
概述
概念
什么是窗口截图
把当前操作的页面, 截图保存到指定位置
为什么要窗口截图
自动化脚本是由程序去执行的, 因此有时打印的错误信息不十分明确
如果在执行出错的时候对当前窗口进行截图保存, 那么就可以非常直观的看到出错的原因
方法
driver.get_screenshot_as_file(imgpath)
案例
验证码处理
概念
什么是验证码
一种随机生成的信息 (数字, 字母, 汉字, 图片, 算术题) 等为了防止恶意的请求行为, 增加应用的安全性
为什么要学习验证码
常用方法
1. 去掉验证码
2. 设置万能验证码
3. 验证码识别技术
4. 记录 cookie
cookie
概念
由web服务器生成的, 并且保存在用户浏览器上的小文本文件, 它可以包含用户相关的信息
数据格式: 键值对组成 (Python中的字典)
产生: 客户端请求服务器, 如果服务器需要记录用户状态, 就向客户端颁发一个cookie数据
使用: 当浏览器再次请求该网站时, 浏览器把请求的数据和cookie数据一起提交给服务器, 服务器检查该 cookie, 以此来辨认用户状态
应用场景
实现会话跟踪, 记录用户登录状态
实现记住密码和自动登录的功能
用户未登录的状态下, 记录购物车中的商品
Selenium操作cookie
方法
获取本网站所有本地cookies
获取指定cookie
添加cookie
案例
需求: 使用cookie 实现跳过百度登录
1. 手动登录百度, 获取cookie
2.请求百度, 并且带上cookie
实现
小结
pytest框架
前言
第一次学习pytest在接口自动化阶段
主要目的是复习和更新少量知识点
我们在未来的移动自动化阶段补全pytest的知识点
总体介绍
什么是框架?
框架的英文单词是 framework
为解决一类事情的功能集合
什么是pytest框架?
是一个第三方单元测试框架, 用它来做单元测试
为什么使用pytest?
能够组织多个用例执行
提供丰富的断言方法
能够生成测试报告
基本使用
安装
安装
通过 pip 命令在线安装
推荐版本 3.10
校验
1. pip list
2. pytest --version
运行方式
介绍
1. 命令行运行
推荐
2. 主函数运行
代码准备
命令行运行
主函数运行
运行结果
断言
总体介绍
什么是断言
让程序代替人工判断测试脚本的执行结果是否符合预期的过程
为什么要学习断言
自动化脚本在执行的时候一般都是无人值守状态
我们不知道执行结果是否符合预期
我们需要让程序代替人工检测执行结果是否符合预期
这就需要断言
方法
assert xx
assert 0
assert 1
判断 xx 为真
assert not xx
判断 xx 不为真
assert a in b
判断 b 包含 a
assert a == b
判断 a等于b
assert a != b
判断 a不等于b
案例
setup和teardown
概念和方法
1. 初始化
setup
2. 销毁
teardown
案例
配置文件
步骤
1. 项目下新建 scripts 模块
2. 测试脚本放到 scripts 中
3. 项目目录下新建一个 pytest.ini 的配置文件
4. 配置文件内容, 第一行为 [pytest]
5. 命令行运行时, 会使用该配置文件中的配置
示例
测试报告插件
应用场景
自动化测试脚本最终执行是否通过, 需要通过测试报告进行体现
安装
pip install pytest-html
建议安装 1.21.1的版本
使用
在配置文件中的命令行参数中, 增加 --html=report/report.html
pytest.ini中, addopts = -s --html=report/report.html
生成步骤
1. 命令行运行 pytest
2. 项目目录下会有一个report文件夹, 里面有个report.html 文件, 它就是测试报告
数据参数化
应用场景
登录功能都是用户名/密码等输入, 点击登录
但是登录的用户名和密码如果想测试多组值时, 就用到数据参数化, 好处是使代码更整洁, 可读性更好
方法
@pytest.mark.parametrize(argnames, argvalues)
argvalues 参数值一般是一个列表
单一参数
案例
多个参数
案例
推荐用法
案例
小结
PO模式
学习路线
v1
不使用任何设计模式和单元测试框架
v2
pytest 管理测试用例
v3
使用方法封装的思想, 对代码进行优化
v4
采用 PO 模式的分层思想对代码进行拆分, 分离page
v5
对PO分层之后的代码继续优化, 分离page中的元素和操作
v6
PO模式深入封装, 把共同的操作提取封装
无模式
案例说明
对 TPshop 项目的登录模块进行自动化测试
登录模块包含了很多测试用例, 为了节省时间, 我们只选取几个有代表性的用例来演示
选择测试用例
账号不存在
密码错误
v1
总体介绍
不使用任何设计模式和单元测试框架
每个文件编写一个用例, 完全的面向过程的编程方式
test_login_account_not_exist.py
test_login_password_error.py
面向过程和面向对象的区别???
示例代码
存在的问题
一条测试用例对应一个文件, 用例多时, 不方便维护管理
代码高度冗余
v2
总体介绍
引入pytest 管理测试用例, 并断言用例的执行结果
好处
方便组织和管理多个测试用例
提供了丰富的断言方法
方便生成测试报告
减少了代码冗余
示例代码
存在的问题
代码冗余
方法封装
封装方法
概念
是将一些有共性的或者多次被使用的代码提取到一个方法中, 供其他地方调用
好处
避免代码冗余
容易维护
隐藏代码实现的细节
目的
用最少的代码实现最多的功能
v3版本
总体介绍
使用方法封装的思想, 对代码进行优化
封装驱动
存在的问题
代码冗余
PO模式介绍
思考
在做UI自动化时定位元素特别依赖页面, 一旦页面发生变更, 就不得不跟着去修改定位元素的代码
driver.find_element_by_id("login-btn").click()
存在的问题
如果开发人员修改了元素的id, 这时候你就不得不修改所有对应的代码
存在大量冗余代码
PO模式概念
PO 是Page Object 的缩写, PO模式是自动化测试项目开发实践的最佳设计模式之一
核心思想
通过对页面元素的封装减少冗余代码, 同时在后期维护中, 若元素发生变化, 只需要调整页面元素封装的代码即可, 提高了测试用例的可维护性, 可读性
页面和测试脚本分离
PO模式分层
分层机制, 让不同层去做不同类型的事情, 让代码结果清晰, 增加复用性
主要分层方式
1.两层
对象操作层
业务数据层
2.三层
对象库
操作层
业务数据层
3.四层
对象库
操作层
业务层
数据层
PO模式的优点
引入PO模式前
存在大量冗余代码
业务流程不清晰
后期维护成本大
引入PO模式后
减少冗余代码
业务代码和测试数据被分开, 降低耦合性
维护成本低
PO模式实践
v4版本
总体介绍
采用PO模式的分层思想对代码进行拆分
封装
对登录页进行封装
类 LoginPage
对测试用例封装
类 TestLogin
结构
utils包
driver_utils.py
page包
login_page.py
scripts包
test_login.py
pytest.ini
PO封装
v5版本
总体介绍
对PO分层后的代码继续优化
优化内容
分离page页面中的元素和操作
优化元素定位的方式
示例代码
PO模式深入封装
v6版本
总体介绍
把共同的方法进行封装
优化内容
封装操作基类
封装查找元素的方法
封装对元素的操作方法: 点击/清空/输入
page继承操作基类
结构
utils包
driver_utils.py
page包
login_page.py
scripts包
test_login.py
pytest.ini
base包
base_action.py
示例代码
小结
数据驱动
数据驱动介绍
概念
是以数据来驱动整个测试用例的执行, 也就是测试数据决定测试结果
特点
可以数据驱动理解为一种模式或者一种思想
数据驱动技术可以让用户把关注点放在对测试数据的构建和维护上, 而不是直接维护测试脚本, 可以利用同样的业务流程, 对不同的输入数据进行测试
数据驱动的实现要依赖参数化的技术
数据来源
直接定义在脚本中
简单直观, 但是代码和数据未实现真正的分离, 不方便后期维护
从文件中读取数据, 如 txt, excel, xml, JSON等格式文件
从数据库中读取数据
JSON操作
JSON基本介绍
概念
JSON全称是" JavaScript Object Notation", 是JavaScript 对象表示法, 它是一种基于文本, 独立于语言的轻量级数据交换格式
特点
是纯文本
具有良好的自我描述性, 便于阅读和书写
具有清晰的层级结构
有效提升网络传输效率
对比
XML 指可扩展标记语言, 被设计用来传输和存储数据
如果使用 XML, 需要读取 XML 文档, 然后通过 XML中的标签结点来遍历文档, 并读取值, 然后存储在变量中
如果使用JSON, 只需要读取JSON字符串
JSON语法规则
大括号保存对象
中括号保存数组
对象和数组可以相互嵌套
数据采用键值对表示
多个数据由逗号分隔
JSON值
数字 (整数或者浮点数)
字符串 (在双引号中)
逻辑值 (true 或 false)
数组 (在中括号中)
对象 (在大括号中)
null
JSON中空值用 null 表示
python中对应的用 None 表示
JSON基本操作
总体介绍
操作内容
python字典与JSON之间的转换
JSON文件读写
注意
在python中想要操作JSON, 需要先导入依赖包
import json
字典与JSON转换
把python字典类型转换为JSON字符串
dumps
把JSON字符串转换为python字典
loads
JSON文件读写
读
load
写
dump
实战一
案例介绍
对tpshop项目的登录模块进行自动化测试, 需要使用数据驱动
为 v6版本 增加数据驱动
实现步骤
1. 编写测试用例
2. 敲代码
1. 采用PO模式的分层思想对页面进行封装
2. 编写测试脚本
3. 定义数据文件, 实现参数化
用例设计
测试脚本参数化
准备工作
新建一个 v7 的 pycharm 项目
把 v6包 中所需的代码复制到 v7项目 中
修改文件中导包处
编写代码
数据文件
新建一个 ./data/login_data.json 文件
数据解析函数
抽离解析函数
实战二
案例介绍
网页计算器, 进行加法的测试操作.
要求: 通过读取数据文件中的数据来执行用例
网址: http://cal.apple886.com/
实现步骤
1. 编写测试用例
1+1
1+2
1+2+3(待定)
2. copy自动化测试框架
3. 修改内容
page
script
data
copy框架代码
修改page文件
编写script脚本
修改JSON数据文件
小结
yaml 跟 JSON
实战项目1和2, 多练习几次
不练习 等于 没学过
日志收集
日志相关概念
概述
概念
日志就是用于记录系统运行时的信息, 也称为Log
作用
调试程序
旧的方式: print("xxxx")
low
新的方式: 通过日志
了解程序运行的情况, 是否正常
程序运行故障分析与问题定位
用来做用户行为分析和数据统计
需要学好 sql
级别
思考
是否记录的所有日志信息重要性都一样?
日志级别, 指日志信息的重要性
常见日志级别
DEBUG
调试
INFO
信息
WARNING
警告
ERROR
错误
CRITICAL
严重错误
日志基本用法
基本用法
logging
python中有一个标准库, logging模块可以直接记录日志
使用
1. 导入 logging 包
2. 输出日志
默认的日志级别被设置为 warning
设置日志级别
方法
logging.basicConfig(level=logging.DEBUG)
设置日志格式
默认格式
日志级别 : Logger名称 : 日志内容
自定义格式
logging.basicConfig(format="xxxxxx")
将日志信息输出到文件
默认
python的logging模块将日志打印到了标准输出中(控制台)
将日志输出到文件的方法
logging.basicConfig(filename="xxx.log")
日志高级用法
总体介绍
思考
如何将日志信息同时输出到控制台和日志文件中?
如何将不同级别的日志输出到不同的日志文件?
如何解决日志文件过大的问题?
四大组件
总体介绍
日志器
Logger
提供了程序使用日志的入口
处理器
Handler
将logger创建的日志记录发送到合适的输出
格式器
Formatter
决定日志的输出格式
过滤器
Filter
提供了更细粒度的控制工具来决定输出哪条日志记录, 丢弃哪条日志记录
组件之间的关系
日志器 (Logger) 是入口, 真正干活的是处理器 (Handler), 处理器还可以通过格式器 (Formatter) 和过滤器 (Filter) 对输出的日志内容做格式化和过滤
Logger类
如何创建Logger对象
logger = logging.getLogger(name)
可选参数 name
如果不写name, 日志器名称默认为 root
如果写了name, 如, logger = logging.getLogger("myLogger")
那么日志器的名称为 myLogger
Logger常用方法
打印日志
logger.debug()
logger.info()
logger.warning
logger.error
logger.critical()
设置日志级别
logger.setLevel()
为logger对象添加一个handler对象
logger.addHandler()
为logger对象添加一个filter对象
logger.addFilter
Handler类
如何创建Handler对象
在程序中不应该直接实例化和使用Handler实例, 因为Handler是一个基类, 它只定义了Handler应该有的接口, 应该使用Handler实现类来创建对象
创建方式
输出日志到控制台
logging.StreamHandler
输出到磁盘文件, 默认文件大小会无限增长
子主题 1
输出到文件, 按文件大小切割
子主题 1
输出到文件, 按时间切割
logging.hanlders.TimedRotatingFileHandler
将日志消息以get或post的方式发送给http服务器
将日志消息发送给一个指定的email地址
常用方法
为handler设置格式器对象
handler.setFormatter()
Formatter类
作用
Formatter对象用于配置日志信息的格式
如何创建Formatter对象
logging.Formatter(fmt=None, datefmt=None)
fmt: 消息格式化字符串, 如果不指定该参数则默认使用message的原始值
datefmt: 日期格式化字符串, 如果不指定该参数则默认使用 "%Y-%m-%d %H:%M:%S"
案例
说明
可读性好的日志需要具备一些特征
在控制台和文件都能输出
文件输出能够按时间切割
步骤
1. 导包
2. 创建日志器对象 / 设置日志级别
3. 创建处理器对象: 输出到控制台 + 文件(按时间切割)
4. 创建格式器对象
5. 将格式器添加到处理器
6. 将处理器添加到日志器
7. 打印日志
示例代码
小结
日志的作用
日志的基本使用
日志的高级用法
项目实战
自动化测试流程
流程步骤
1. 需求分析
2. 挑选适合做自动化测试的功能
人力不充足: 选择冒烟测试相关用例
人力充足: 可以考虑100%执行功能测试的用例
3. 设计筛选测试用例
4. 搭建自动化测试环境[可选]
5. 设计自动化测试项目的架构[可选]
6. 编写代码
7. 执行测试用例
8. 生成测试报告并分析结果
对比
项目介绍
如何介绍[复习]
四个步骤
1. 业务特性
2. 用户和角色
3. 功能模块
4. 技术栈
项目案例介绍
**项目名称**
TPshop开源商城系统
**项目描述**
TPshop是一个电子商务B2C电商平台系统,功能强大,安全便捷。适合企业及个人快速构建个性化网上商城
> 包含PC+IOS客户端+Adroid客户端+微商城,系统PC+后台是基于ThinkPHP MVC构架开发的跨平台开源软件,设计得非常灵活,具有模块化架构体系和丰富的功能,易于与第三方应用系统无缝集成,在设计上,包含相当全面,以模块化架构体系,让应用组合变得相当灵活,功能也相当丰富
**项目架构**
windows + php + apache + mysql
用例设计
编写规则
自动化测试用例一般只实现核心业务流程或者重复执行率较高的功能
自动化测试用例的选择一般以"正向"逻辑的验证为主
不是所有手工测试用例都可以使用自动化测试来执行
尽量减少多个用例脚本之间的依赖
自动化测试用例执行完毕后, 一般需要回归原点
编写测试用例
搭建框架
新建项目
前提条件
依赖包安装
Selenium
pytest
pytest-html
项目名称
项目初始化
搭建框架, 不写具体代码
丰富了项目目录
延用了 base 和 utils 包中的文件
编写代码
抽取PO
定义页面对象文件
首页: index_page.py
登录页: login_page.py
个人中心页: home_page.py
商品搜索页: goods_search_page.py
商品详情页: goods_detail_page.py
购物车页: cart_page.py
下订单页: order_page.py
订单支付页: order_pay_page.py
编写页面对象代码
编写测试脚本
定义脚本文件
建议每个功能模块对应一个py文件
登录模块: test_login.py
写脚本
数据驱动: 登录数据的参数化
处理登录
1 每次都登录
low
2 使用cookie
通用
3 使用开关控制浏览器的关闭
适用于业务有顺序的情况
开关默认关闭, 浏览器可关闭
打开开关后, 浏览器不可自动关闭
购物车模块: test_cart.py
写脚本
查看进程管理器, 可以手动关闭chromedrvier.exe 这些没有释放的进程
订单模块: test_order.py
写脚本
测试用例运行, 发现定位元素 "货到付款" 失败了
切换定位元素的方法重新定位
测试用例都能正常运行
存在问题: 浏览器依然没有关闭
通过 teardown_class 方法最后执行结束关闭了浏览器驱动
使用pytest管理测试脚本
完善代码
数据驱动
定义数据文件
1. 定义目录
定义存放测试数据文件的目录, 如, data
2 分模块定义数据文件
login_data.json
cart_data.json
order_data.json
3. 根据业务编写用例数据
测试脚本参数化
@pytest.mark.parametrize() 完成参数化
**参考UnitTest
日志收集
日志配置
在 config 包下 新建一个 logging_config.py 文件
配置文件加载
考虑到脚本的执行需要加载日志配置文件 并且输出日志
考虑到驱动获取和关闭的方法也有可能需要输出日志
那么选择在 utils 包下的 __init__.py 文件中执行加载日志配置的方法
输出日志
屏幕截图
测试报告
小结
一定要有思路, 先动手, 再解决遇到的难点
方案
自动化项目实施方案
1、项目概述MAJOR HEAT
1)文档目的:
本文是自动化产品在(某国有银行,这里以青胜银行作为代替昵称)青胜银行POC环境中的具体规划、实施和测试方案。阐述POC测试环境下需要的硬件资源和软件资源,列出了系统的测试功能列表和用例。
2)项目背景:
青胜银行经过多年的运维平台建设,已经初步建成了包含基础监控和应用监控的监控系统、正在建设ITIL流程平台;能够做到了故障发现、故障定位、故障跟踪,以及事件管理、问题管理、变更管理以及配置管理等相关功能。为了更好的解放人力,提高各种操作的标准化程度,计划测试包括虚拟化平台管理(例如:虚拟机的新建、回收和划盘等基本管理操作)、物理主机(x86和小机)管理(例如:批量装机,软硬件监控等管理)、网络设备管理、存储设备管理和批量任务调度等,希望与监控、流程一起实现一定的监、管、控的能力。
3)项目人员:
子主题 1
4)测试范围:
自动化系统在运维平台体系中的作用
自动化操作系统在智能一体化平台中通过对巡检、系统部署、应用部署、配置信息抓取等实现自动化的操作,一方面能够使运维人员真正的从一些重复的、一般性的工作中解脱出来,发挥运维人员更大的价值;另一方面使运维操作能够更加规范化,方便进行安全管控,避免运维中的安全风险。
智能一体化运维平台伴随着自动化运维能力的建设,将会为运维平台提供自由扩展的服务能力,在运维资源有限的情况下满足持续增加的运维服务需求。
自动化系统功能要点概述
子主题 1
IT自动化操作系统分为操作执行层,操作控制层以及操作定义层:
操作执行层
本层具体负责IT运维中具体实施的最终操作,包括面向服务器类以及面向网络设备类的操作。面向服务器类操作通过在服务器上部署统一的代理,实现集中的调度和控制;面向网络设备类操作,则需要通过提供不同设备类型所提供的控制接口进行统一管理。
操作控制层
操作控制层通过专有的操作安全控制软件和控制设备,与服务流程系统流程审批、集中监控系统的日志监控,以及数据分析系统的安全审计相结合,由审批流程对操作控制进行事前的审批、日志监控对控制软件和设备操作日志进行事中的监控、安全审计对事后的变更内容进行监督,实现服务器、数据库、网络的操作的精细化管控。
操作定义层
操作定义层负责具体的自动化操作运维场景的定义和编排,从操作任务管理、 操作协同调度以及应急调度几个角度出发,将银行自动化操作归纳成一个个自动化运维场景,以便于IT运维人员更好的进行管理与配置。
子主题 4
本次POC过程主要验证如下功能点:
1、云平台虚拟化功能:如虚拟机的创建等生命周期管理;虚拟机的监控;
2、云平台x86物理机功能:如x86物理机的自动安装操作系统;系统监控;
3、批量调度功能实现
5)时间计划:
子主题 1
6)设备清单:
硬件资源:
子主题 1
网络要求:
子主题 1
批量任务调度硬件资源:
子主题 1
2、云平台自动化系统架构介绍:MAJOR HEAT
1)功能架构:
子主题 1
云管理平台(SkyForm系统)在物理资源层、虚拟化环境(包括虚拟化平台、虚拟化资源接口层)基础上,由资源管理、运营管理、门户、开放接口,以及安全、监控管理体系组成。
资源管理对计算、存储等物理资源进行池化,抽象成可管理、可调度的逻辑资源,屏蔽异构虚拟化平台(包括VMware、KVM和XenServer等)调用接口并统一管理调度,向上提供一致化的访问;
运营管理包括服务运营,服务管理。运营是指服务的订购和加载,实现云服务的开通;服务管理是指服务的SLA管理、计量管理、服务监控,以及统计分析等功能;
门户包括用户门户和管理门户,用户门户面向企业用户/公众用户提供业务申请、使用查询等自助服务接入;管理门户面向运营和运维管理人员,提供业务运营和管理、平台管理、虚拟资源管理,以及安全管理的统一服务接入。
云管理平台作为一个开放的平台架构,允许用户通过它提供的系统接口二次开发,以及可以集成现有的各种系统和管理工具,如网管、认证与授权系统、审批系统、计费、资产等,在不改变用户业务逻辑和流程的情况下,实现资源的整合、管理与交付。
做为云平台的不可缺少的辅助,还提供了云服务监控、故障管理和云安全体系做为支撑。
2)物理机自动部署介绍:
物理采用PXE方式自动部署,具体过程如下:
子主题 1
具体
1. 目标 主机发送 DHCP 请求。
2. DHCP 服务器使用 IP 信息响应请求,并提供有关 TFTP 服务器位置的信息。
3. 客户端收到信息时,它会联系 TFTP 服务器,请求 DHCP 服务器指定的文件(在此情况下为网络引导加载程序)。
4. TFTP 服务器发送网络引导加载程序,然后客户端开始执行引导。
5. PXELINUX 或 gPXE 在 TFTP 服务器上搜索配置文件(01-MAC) ,并根据该配置文件引导内核。在我们所述的情况中,配置文件将指示 PXE 加载内核 (vmlinuz) 和 ramdisk (initrd.img)。
6. 客户端下载它需要的文件,然后进行加载。
7. 系统引导 OS 安装程序。
8. 按照 PXE 配置文件的指示,安装程序将以应答方式运行(answerfile)。
9. 安装程序使用存储在网络上的介质库中的安装介质。
10. OS安装成功。
3、项目实施规划:MAJOR HEAT
1)系统组网:
子主题 1
子主题 1
说明:
此组网针对POC场景,最小规模组网。
分为3个域,云平台管理域、虚拟机资源域和x86物理机资源域
云平台管理域:主要部署云平台的管理服务,包括虚拟机模块的服务和物理机模块的服务。
虚拟机资源域:主要是虚拟化用的x86服务器。
x86物理机资源域:主要是非虚拟化用的服务器
2)物理机自动部署规划:
子主题 1
说明:
上图示意了3个vlan下的x86物理机的部署结构,poc环境下,测试一个vlan就行。
每个vlan需要部署个dhcp server。dhcp server跟管理网是通的。
待测试的物理机需要2台,主要是为了测试批量部署功能。
3)设备命名规划:
设备命名需遵循以下原则:
1. 格式:机架号-机房名称-网络层次-项目名称-网络设备类型+3位阿拉伯数字-厂家型号
2. 项目名称:资源池,简称ZYC
3. 网络设备类型:常见的RT代表路由器、FW代表防火墙、SW代表交换机,包括光纤交换机、SV代表服务器
4. 厂家型号:以厂家发货为准,字节要求根据实际为4~7个字节。
5. 补充说明:
6. 同一种设备类型,在同一个网络层次,序号递增,即网络设备类型后面带的3为阿拉伯数字,如001.
7. 刀片服务器,一个刀框一个逻辑名,不分刀片数目。刀片的具体使用将在“刀片服务器设备使用情况表”具体说明。
8. 相同作用的设备,设备序号按架位号从A到J排列,并由上到下,由左到右的原则进行命名。即上面的序号小,左边的序号小
9. 目前以该设备命名列表为准,接下来的施工有变更架位好,只需更改架位号信息,其他内容不做更改。
4)VLAN规划:
网络规划一般包括云平台管理网络,各资源池网络、存储网络等;
平台管理网络:需要两个网络段;
存储网络:使用现有资源池规划地址;
各资源池网络:根据具体纳管的情况划分,一般使用现有的网络段;
内部网络安全策略主要通过访问控制(ACL和防火墙)来实现不同网络、不同业务系统间的访问和隔离。
子主题 1
5)云管理平台规划:
n 云管理平台vlan划分
子主题 1
管理段、Public段属于云管理平台管理网。
云管理平台节点规划:
a) 管理节点
云管理平台(SkyForm)需要一定规模的计算资源来承载其管理业务和资源池,至少需要两台物理机组建一个集群来承载相关虚机。POC环境下需要1台X86物理机资源即可,然后我们在此物理机上创建虚拟机,安装云管理平台的各个服务。
操作系统的用户名、密码统一设置为:root/abc@123
b) 虚拟化模块管理服务关系图
子主题 1
子主题 2
c) 物理机模块管理服务关系图
子主题 1
子主题 2
6)存储规划:
虚拟化系统的存储规划
SkyForm云管理平台使用两种类型的存储:高性能的存储(主存储)用于存储虚拟机的操作系统和数据;低性能的存储(二级存储)用于存储虚拟机的模板文件和快照。
主存储的大小与业务的规划有密切关系。例如虚拟机的标准配置为40G系统盘和60G应用盘,那么100个虚拟机的需要的主存储空间为10T。
二级存储的大小与云管理平台中虚拟机的备份策略有关系。备份时时间间隔越短,要求的备份空间就越大。另外,使用增量备份使用的存储空间比全量备份的空间少。
针对POC环境,需要的存储容量如下:
子主题 1
4、部署方案MAJOR HEAT
1)部署详细步骤
在项目计划的时间范围内,完成如下实施工作:
统一配置功能:
1. 准备工作,配置好网络,管理网、业务网,存储网
2. 规划好管理网、存储网、业务网IP地址,包括云管理平台所需IP地址
虚拟机功能配置相关:
3. 配置服务器IPMI,安装ESXI
4. 安装云管理平台管理服务器所需模板,部署vcenter并考虑冗余机制
5. 创建vmware集群,包括管理和计算节点集群,配置并连接存储网络
6. 创建云管理平台管理服务器模板
7. 创建云管理平台各角色虚拟机
8. 部署云管理平台,包括SkyForm资源管理平台、数据库、二级存储等并考虑冗余
9. 添加SkyForm云管理平台资源域、机架、集群、主机、主存储、二级存储,建立起云管理平台基础架构;
10. 在VMWare集群中,将虚拟机模板以服务形式发布出来,完成流程化申请;
11. 纳管配置存储设备,并在资源管理平台管理 存储;
12. 纳管配置网络设备,将交换机和防火墙纳入到网络拓扑和监控系统中;
物理机功能配置相关:
13. 配置待部署物理机,满足下面条件
▲待部署物理机必须支持 IPMI n
▲待部署物理机必须支持PXE 网络启动,(有些服务器默认没有打开PXE 网络启动 需要进 BIOS 设置,如下图)
▲待部署物理机的第一启动顺序必须设置成从硬盘启动。不能设置成网络启动,否则物理机将一直从网络引导,造成不停循环安装操作系统。
14. 安装云平台的物理机服务模块安装包
15. 将物理机相关的ISO上传到FTP server。
16. 在云平台创建物理机资源池,添加待部署的物理机信息
测试和记录测试结果,用户培训
17. 系统测试;
18. 用户培训等。
2)云平台资源池划分:
虚拟机资源池规划
子主题 1
物理机池规划
子主题 1
3)云平台安装:
准备操作系统模板
配置好IP地址、hostname、dns、做好yum源、ntp服务
SkyForm安装,请见《SkyForm云平台V4.1 安装指南.pdf》
SkyForm物理机安装,请见《SkyForm云平台企业版 物理机模块安装指南.pdf》
POC环境部署和配置云平台功能模块
4)批量任务调度平台安装:
安装批量任务调度平台服务程序,请见《自动化系统服务端部署-sop.doc》
安装批量任务调度平台代理程序,请见《自动化系统代理端部署-sop.doc》
5、测试用例MAJOR HEAT
1)虚拟机资源池主要测试用例:
vSphere资源池纳管
子主题 1
子主题 2
门户API接口
子主题 1
代开虚拟机
子主题 1
云主机备份/快照
子主题 1
自定义告警规则
子主题 1
配额维护
子主题 1
资源概要
子主题 1
其他用例
请参考附件《SkyForm4.1测试用例.xlsx》
2)物理机资源池主要测试用例:
添加物理机资源池
子主题 1
添加物理机
子主题 1
物理机远程开关机
子主题 1
物理机远程部署操作
子主题 1
3)批量任务调度主要测试用例:
增加代理程序
子主题 1
执行批量任务
子主题 1
读取调度日志
子主题 1
分支主题 5
接口自动化
数据库以及数据库操作
数据库概述
概念
数据库: 存储数据的仓库, 程序中数据的载体
分类
关系型数据库: 安全
如, mysql oracle SQLite...
database
tables
行+列
非关系型数据库: 高效
如, redis mongoDB...
数据存储结构多样
键值对, 列表, 字符串...
作用
数据库和变量都可以存储数据, 二者有什么区别?
持久性不同: 数据库可以持久性存储数据(把数据写入磁盘文件), 变量不能(运行在内存中)
python操作数据库的相关实现
背景
python(等各种编程语言)本身不具备直连数据库的功能, 必须导入第三方包
相关实现
驱动
MySQLdb
mysqlclient
(重点) PyMySQL
小结
什么是数据库?
数据库和变量都可以存储数据, 二者有什么区别?
数据库的分类有哪些? 请举例
用python操作数据库的驱动, 你熟悉哪个?
pymysql基础
总体介绍
安装
在线安装
命令行运行 pip install pymysql 回车
出现 Successfully installed xxxx 字样, 代表安装成功
校验
命令行运行 pip list 回车
列表中查找到 pymysql 和 版本号 就说明安装成功
流程
1 创建了一个桥
创建了一个连接connection
2 创建了一个驴
获取了一个游标cursor
3 执行 sql 语句
执行 查询 语句
执行 增/删/改 语句
判断是否出现异常
否(没有出现异常)
提交事物
是(出现异常)
回滚事务
4 卸磨杀驴
关闭游标 cursor
5 过河拆桥
关闭连接 connection
基本操作框架
python使用 pymysql 连接数据库, 不论增删改查, 流程基本一致
编码流程
1.导包
2.创建连接
3.获取游标
4.核心: 发送sql语句
5.释放资源
先游标后连接
小结
如果让你使用python的 pip 命令去安装一个包, 应该如何操作?
如何校验 pip 安装的包是否安装成功?
能够说出python使用pymysql操作数据库的流程?
pymysql核心操作-增删改查
查
核心代码编写过程
1. 编写sql语句
2. 执行sql语句
游标对象.execute(要执行的语句)
3. 获取响应结果
获取响应结果行数
游标对象.rowcount
逐行获取数据
游标对象.fetchone()
返回一个元组
获取所有数据
游标对象.fetchall()
返回一个元组
增删改
核心代码编写过程
同上
小结
使用pymysql做mysql的增删改查操作, 编码步骤有哪些?
实际编写代码完成增删改查的操作?(提交4个脚本)
pymysql核心操作-事务
概念
举例
银行转账
用户A需要转账给用户B 100块钱
过程简介
1 用户A账户减100
2 用户B账户加100
概念
一套完整的业务逻辑, 在这套业务中可能包含多条sql语句, 这些sql执行时, 要么都成功, 要么都失败
特征(面试常见)
原子性
事务中包含的操作被看作一个逻辑单元, 这个单元中的操作要么都成功, 要么都失败
一致性
逻辑单元中的操作不应该一部分成功一部分失败
孤立性
事务的中间状态对其他事务是不可见的
持久性
指一个事务一旦提交成功, 它对数据库中数据的改变应该是永久性的
事务提交机制
概念
提交: commit, 将修改写入数据库
回滚: rollback, 拒绝将修改写入数据库
方式
手动提交[推荐]
连接对象.commit()
自动提交
创建连接时设置 autocommit=True
事务操作
需求
向 t_area 表插入信息, 先插入A, 再插入B, 要么都成功, 要么都失败
前提
MyISAM 不支持事务(旧版mysql的默认引擎)
InnoDB 支持事务(较新版本mysql的默认引擎)
修改数据库引擎
执行 show ENGINES 查看当前 mysql 支持的引擎都有哪些
执行 ALTER TABLE t_area ENGINE=INNODB 修改表 t_area 的引擎为 InnoDB
流程
用 try 语句控制
小结
用举例来说明什么是事务?
[面试题]事务有哪些特征?
需求
向 t_area 表中依次插入ABC三条信息, 要么都成功, 要么都失败?
pymysql工具类封装
需求
将获取连接, 获取游标, 以及释放资源这些重复性操作, 进行封装, 需要时, 再调用
封装
调用
小结
根据需求进行封装, 并且完成增删改的数据库操作脚本
接口自动化测试
概念
程序驱动代替人工驱动实现接口测试
实现方式
工具
postman
jmeter
...
编码
python
java
...
比较
工具
优点: 1.不需要编程基础 2.功能都是封装好的, 直接调用
缺点: 不灵活
编码
优点: 灵活(扩展性好)
缺点: 1.需要编程基础 2.功能需要自实现, 效率偏低
requests库
概述
概念
requests库是使用 python 编写的, 可以调用该库的函数直接向服务器发送请求, 并接收响应
角色定位
相当于 jmeter 中的 http 请求
安装
在线安装
在命令行输入 pip install requests
校验
在命令行输入 pip list 找到 requests库的名称和对应的版本号即可
基本实现请求
GET
需求
编写 python 代码, 访问案例的查询接口 http://localhost:8081/sa/listarea
POST
需求
访问案例的新增接口 http://localhost:8081/sa/addarea
参数: areaName 和 priority
PUT
需求
访问案例的修改接口 http://localhost:8081/sa/modifyarea
参数: Json格式
{
"areaId": "xxx",
"areaName": "yyy",
"priority": "zzz"
}
DELETE
需求
访问案例的删除接口 http://localhost:8081/sa/removearea
参数: areaId
补充
四种操作代码结构基本一致
导包
操作
要素1和2
获取响应
要素3
区别
1 函数名不同(对应的请求方式不同)
2 提交数据的参数名不同
get 和 delete 使用 params 提交数据
post 和 put 使用
data 提交键值对数据
json 提交JSON格式的数据
为什么 get/delete 和 post/put 提交数据使用的参数不一致?
get/delete 请求格式
在请求行
用 params
post/put 请求格式
在请求体
用 data/ json
基本实现响应
行
头
体
登录案例
实现思路
需求案例
先登录, 登录成功后获取 "我的订单" 页面
login接口 (post)
键值对提交数据
username 和 password
order_list 接口 (get)
cookie
例如, 使用 jmeter 请求百度搜索接口时, 会经常帮我们跳转到安全认证页面, 原因是我们没有cookie, 也就是没有身份, 百度不认识我们
解决方式, 我们从浏览器拿了一个 BAIDUID , 并使用cookie管理器组件进行管理
存在问题: 获取cookie后, 后面每一个接口实现都需要提交cookie, 过程高度重复, requests库内置了相关实现的封装, 封装了对 cookie 的处理
session
注意点: requests中的 session 是对 cookie的封装, 并不是服务器端的 session, 二者无关, 只是重名
实现
需求
使用 requests库调用 tpshop登录功能的相关接口, 完成登录操作, 登录成功后获取 "我的订单" 页面(访问订单列表接口)
cookie实现
session实现
小结
requests库有什么用?
使用 requests库实现案例的增删改查4种接口的请求并获取响应结果
状态码
响应体
掌握session实现方案: 用session去实现
需求
使用 requests库调用 tpshop登录功能的相关接口, 完成登录操作, 登录成功后获取 "我的订单" 页面(访问订单列表接口)
pytest
概述
思考
一条测试用例, 并对应着一个py文件
如何执行
pycharm中邮件 run...
多条测试用例呢? (可能对应着1个py文件 也可能对应多个py文件)
如何执行
执行方式是调用
概念
pytest是python的一种第三方的单元测试框架
特点
同自带的 unittest测试框架类似, 相比于 unittest框架使用起来更简洁, 更高效
安装
在线安装
命令行输入 pip install pytest 回车就可以啦
注意: 兼容问题, 推荐使用的 pytest 版本号为 3.10
命令行输入 pip install pytest==3.10 回车, 可以安装指定版本的 pytest
卸载
命令行输入 pip uninstall pytest 回车
校验
方式1
命令行输入 pytest --version 回车
方式2
通用的方式 命令行输入 pip list
运行
代码准备
运行方式
运行结果
setup和teardown
概念
函数级
运行于测试方法的始末, 运行一次测试函数就好执行一次setup和teardown
...
配置文件
概述
思考
不用配置文件的方式
pytest 会找到项目下的 test_xxx开头的py文件
以及该文件群下的 Test 开头的类
以及类下面 test 开头的函数
符合要求的测试函数都会被执行
使用配置文件
可以通过配置项来选择执行哪些目录下的哪些模块
更灵活
使用方式
1 项目下新建一个 scripts 模块
2 将测试脚本放到 scripts 中
3 pytest 的配置文件放在自动化项目目录下
4 配置文件名称为 pytest.ini
5 pytest.ini 第一行的内容为 [pytest] , 后面逐行写具体的配置参数
6 命令行运行时会使用该配置文件中的配置
实现
数据参数化
应用场景
例如, 登录功能都是出入用户名/密码, 如果想测试多组值时, 数据参数化可以使代码更简洁
方法
@pytest.mark.parametrize("参数名", 参数值)
测试报告插件
应用场景
自动化测试脚本最终执行是否通过, 需要用测试报告来进行体现
插件安装
在线安装
命令行输入 pip install pytest-html 回车进行安装
建议使用 pip install pytest-html==1.21.1
因为pytest-html最新出到2.0以上版本了, 有部分兼容性问题
使用
增加参数 --html=用户路径/xxx.html
命令行直接增加
在 pytest.ini 中 增加
addopts = -s --html=report/report.html
结果
运行代码后, 在项目目录下会产生一个 report文件夹(包), 里面有个 report.html 的文件, 就是测试报告
集成思路
目的
集成的目的: 框架化测试用例的执行
非规范化实现思路
# 创建测试类
# 初始化函数
# 资源销毁函数
# 测试函数
小结
需求
使用pytest的配置文件方式运行测试项目 scripts 下的脚本文件, 并且产生html测试报告
test_demo1.py
有两个测试函数, 一个断言成功, 另一个断言失败
test_demo2.py
有一个测试函数, 要求参数化运行3次
接口自动化框架实现
接口自动化流程
测试用例设计
简写
描述
要素1和2
要素1 (url, 请求方式)
要素2 (要提交的数据)
要素3
关注较多的是 状态码 和 响应体
框架架构图解
创建框架结构
框架实现
需求
用接口自动化框架实现对案例 (api-1.0.jar) 增删改查接口的自动化测试
小结
如果想顺利的熟练的掌握接口自动化框架知识, 需要多敲多练
0 条评论
下一页