当前位置: 首页 > ds >正文

五、UI自动化测试05--PyTest框架

目录

  • 一、PyTest 框架
    • 2. 特点
    • 2. 安装步骤
    • 3. 基本使⽤
      • 3.1 测试函数形式
      • 3.2 执⾏⽅式
      • 3.3 测试类形式
      • 3.4 执⾏⽅式
      • 3.5 另⼀种执⾏⽅式: 主函数执⾏
      • 3.6 特殊⽅法: 函数级别
      • 3.7 特殊⽅法: 类级别
      • 3.8 特殊⽅法: 函数级别和类级别同时使⽤
    • 4. pytest 配置⽂件
      • 4.1 选项字段获取
      • 4.2 编写步骤
      • 4.3 使⽤步骤
      • 4.4 默认设置
      • 4.5 ⾃定义规则
      • 4.6 扩展: 指定单个⽂件/类/⽅法执⾏
  • 二、 pytest 常⽤插件
    • 1. HTML 报告插件
      • 1.1 安装步骤
      • 1.2 使⽤步骤
    • 2. 控制⽅法执⾏顺序插件
      • 2.1 安装步骤
      • 2.2 使⽤步骤
    • 3. 失败重试插件
      • 3.1 安装步骤
      • 3.2 使⽤步骤
  • 三、pytest ⾼级功能
    • 1. 跳过操作
    • 2. 参数化操作
      • 2.1 单个参数
      • 2.2 多个参数
    • 3. 扩展: 断⾔⽅法的使⽤
      • 3.1 Python ⾃带的断⾔⽅法
      • 3.2 pytest 框架中使⽤断⾔
  • 四、PO 设计模式
    • 1. v0 版本
    • 2. 账户不存在脚本
    • 3. 密码错误脚本

一、PyTest 框架

  • 说明: pytest 是 Python 的⼀种单元测试框架,同⾃带的 UnitTest 测试框架类似,相⽐ UnitTest 框架使⽤起来更简洁,效率更⾼。(在⾃动化测试中同样充当测试执⾏的功能! 并且可以跟 UnitTest 互换)

2. 特点

    1. ⾮常容易上⼿,⼊⻔简单,⽂档丰富,⽂档中有很多实例可以参考
  • 官⽅⽂档地址: https://docs.pytest.org/en/6.2.x/
    1. ⽀持简单的单元测试和复杂的功能测试
    1. ⽀持参数化: UnitTest 需要通过插件扩展参数化功能!
    1. 执⾏测试过程中可以将某些测试跳过,或者对某些预期失败的 Case 标记成失败
    1. ⽀持重复执⾏失败的 Case : 通过安装插件实现
    1. ⽀持运⾏由 Nose,UnitTest 编写的测试 Case : pytest 框架的脚本在 UnitTest 下⽆法执⾏
    1. 具有很多第三⽅插件,并且可以⾃定义扩展
  • 插件获取⽹站:
    • https://docs.pytest.org/en/latest/reference/plugin_list.html
    1. ⽅便的和持续集成⼯具集成

2. 安装步骤

说明: 与 UnitTest 不同的是, pytest 框架需要先安装才能使⽤!

  • 安装:
    • pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pytest
  • 查看: pip show pytest
  • 确认版本: pytest --version

安装与查看版本步骤

在这里插入图片描述

3. 基本使⽤

3.1 测试函数形式

# 函数形式
def test_func(): # 要求函数名以 test 开头"""测试函数"""print('我是测试函数')

3.2 执⾏⽅式

在这里插入图片描述

3.3 测试类形式

# 测试类形式
class TestDemo(object): # 正常定义类, 但是测试类名必须以 Test 开头"""测试示例类"""def test_method1(self): # 正常定义⽅法, 但是测试⽅法名必须以 
test 开头"""测试⽅法1"""print('测试⽅法1')def test_method2(self):"""测试⽅法2"""print('测试⽅法2')

3.4 执⾏⽅式

在这里插入图片描述

3.5 另⼀种执⾏⽅式: 主函数执⾏

说明: 使⽤主函数, 可以实现在代码⽂件内, ⿏标右键菜单执⾏

  • 测试函数形式下使⽤
# 测试函数形式
import pytestdef test_func(): # 要求函数名以 test 开头"""测试函数"""print('我是测试函数')if __name__ == '__main__':# 语法: pytest.main(['-s', '⽂件名.py'])pytest.main(['-s', 'hm03_pytest_basic_03.py'])
  • 测试类形式下使⽤
# 测试类形式
import pytestclass TestDemo(object): # 正常定义类, 但是测试类名必须以 Test 开头"""测试示例类"""def test_method1(self): # 正常定义⽅法, 但是测试⽅法名必须以 test 开头"""测试⽅法1"""print('测试⽅法1')def test_method2(self):"""测试⽅法2"""print('测试⽅法2')if __name__ == '__main__':# 语法: pytest.main(['-s', '⽂件名.py'])pytest.main(['-s', 'hm04_pytest_basic_04.py'])

3.6 特殊⽅法: 函数级别

  • 说明: 函数级别特殊⽅法的执⾏逻辑与 UnitTest 中的 Fixture 的⽅法级别的执⾏逻辑⼀致!
"""
特殊⽅法: 函数级别
"""
import pytestclass TestDemo(object):"""测试示例类"""# 说明: 特殊⽅法名写法固定, 没有代码提示, 需要⼿写!# 注意: 函数级别执⾏顺序: # 先 setup() -> 测试⽅法1 -> teardown() ⽅法, 再 setup() -> 测试⽅法2 -> teardown() ⽅法def setup(self):"""开始⽅法"""print('函数 -> 开始')def teardown(self):"""结束⽅法"""print('函数 -> 结束')def test_method1(self):"""示例测试⽅法"""print('测试⽅法1')def test_method2(self):"""示例测试⽅法"""print('测试⽅法2')if __name__ == '__main__':pytest.main(['-s', 'hm05_pytest_basic_05.py'])

3.7 特殊⽅法: 类级别

  • 说明: 类级别特殊⽅法的执⾏逻辑与 UnitTest 中的 Fixture 的类级别的执⾏逻辑⼀致!
"""
特殊⽅法: 类级别
"""
import pytest
class TestDemo(object):"""测试示例类"""# 说明: 特殊⽅法名写法固定, 没有代码提示, 需要⼿写!# 注意: 类级别执⾏顺序:# 先 setup_class() -> 测试⽅法1 -> 测试⽅法2 -> 
teardown_class() ⽅法def setup_class(self):"""开始⽅法"""print('类 -> 开始')def teardown_class(self):"""结束⽅法"""print('类 -> 结束')def test_method1(self):"""示例测试⽅法"""print('测试⽅法1')def test_method2(self):"""示例测试⽅法"""print('测试⽅法2')if __name__ == '__main__':pytest.main(['-s', 'hm06_pytest_basic_06.py'])

3.8 特殊⽅法: 函数级别和类级别同时使⽤

"""
特殊⽅法: 函数级别和类级别同时使⽤
"""
import pytestclass TestDemo(object):"""示例测试类"""# 执⾏顺序: 1 -> 3 -> 5 -> 4 -> 3-> 6 -> 4 -> 2def setup_class(self): # 1print('类级别 ->> 开始')def teardown_class(self): # 2print('类级别 ->> 结束')def setup(self): # 3print('函数级别 -> 开始')def teardown(self): # 4print('函数级别 -> 结束')def test_method1(self): # 5"""测试⽅法1"""print('测试⽅法1')def test_method2(self): # 6"""测试⽅法2"""print('测试⽅法2')if __name__ == '__main__':pytest.main(['-s', 'hm07_pytest_basic_07.py'])

4. pytest 配置⽂件

  • 说明: 使⽤配置⽂件后可以快速的使⽤配置的项来选择执⾏哪些测试模块
  • 注意:
      1. 在 Windows 系统下, pytest 配置⽂件中, 不允许写注释信息
      1. ⼀个⼯程内只需要⼀个 pytest 配置⽂件, 并且需要保证⽂件名正确
      1. ⼀般情况, 只需要将 pytest 配置⽂件, 置于⼯程根⽬录下
      1. 配置有 pytest 配置⽂件的⼯程, 只需要打开命令⾏, 输⼊ pytest 指令, 即可执⾏测试

4.1 选项字段获取

在这里插入图片描述

4.2 编写步骤

在这里插入图片描述

4.3 使⽤步骤

  • 说明: 打开命令⾏ -> 输⼊ pytest -> 执⾏即可

4.4 默认设置

  • 说明: 测试⽤例⽂件名/测试类名/测试⽅法名均为 Test/test 开头

[pytest]
testpaths = ./case
addopts = -s
python_files = test*.py
python_classes = Test*
python_functions = test*

4.5 ⾃定义规则

  • 说明: 测试⽤例⽂件名/测试类名/测试⽅法名, 需要根据具体项⽬进⾏设置, 以下以 Hm/hm为例

[pytest]
testpaths = ./case
addopts = -s
python_files = hm*.py
python_classes = Hm*
python_functions = hm*

4.6 扩展: 指定单个⽂件/类/⽅法执⾏

[pytest]
testpaths = ./case
addopts = -s
python_files = demo_case1.py
python_classes = DemoDemo1
python_functions = demo_method1

二、 pytest 常⽤插件

1. HTML 报告插件

1.1 安装步骤

  • ⽅式1 -> 安装: pip install pytest-html
  • ⽅式2 -> PyCharm 中安装

在这里插入图片描述

1.2 使⽤步骤

    1. 在 pytest 配置⽂件中, 增加命令选项
    • 选项: --html=./报告路径/报告⽂件名.html --self-contained-html
    • 说明: --self-contained-html 将 CSS ⽂件内嵌到报告⽂件中
    1. 执⾏ pytest 指令, 运⾏测试即可
  • 添加命令选项执⾏
    在这里插入图片描述

  • 查看⽣成的报告内容
    在这里插入图片描述

2. 控制⽅法执⾏顺序插件

2.1 安装步骤

  • ⽅式1 -> 安装: pip install pytest-ordering
  • ⽅式2 -> PyCharm 中安装

在这里插入图片描述

2.2 使⽤步骤

  • 说明: 直接在测试类或测试⽅法上⽅添加 @pytest.mark.run(order=序号)
"""
pytest 控制⽅法执⾏顺序插件
"""
import pytest@pytest.mark.run(order=2)
class TestDemo(object):"""示例测试类"""# 语法: @pytest.mark.run(order=序号)# 注意: run(order=序号) 没有代码提示, 需要⼿写!# @pytest.mark.run(order=-3)def test_method1(self):"""测试⽅法1"""print('测试⽅法1')# @pytest.mark.run(order=1)def test_method2(self):"""测试⽅法2"""print('测试⽅法2')# @pytest.mark.run(order=2)def test_method3(self):"""测试⽅法3"""print('测试⽅法3')# 扩展: 序号⽀持正数和负数, 以及正负混合# 1. 纯正数: 数越⼩, 优先级越⾼[掌握]# 2. 纯负数: 数越⼩, 优先级越⾼[了解]# 3. 正负混合: 正数先按照顺序执⾏, 负数最后执⾏[了解]# 注意: 控制⽅法执⾏顺序对测试类同样有效!
@pytest.mark.run(order=1)
class TestDemo2(object):"""测试类2"""def test_method(self):print('测试类2 -> 测试⽅法')

3. 失败重试插件

3.1 安装步骤

  • ⽅式1 -> 安装: pip install pytest-rerunfailures
  • ⽅式2 -> PyCharm 中安装

在这里插入图片描述

3.2 使⽤步骤

    1. 在 pytest 配置⽂件中, 增加命令选项
    • 选项: --reruns 次数
    1. 执⾏ pytest 指令, 运⾏测试即可
      在这里插入图片描述

三、pytest ⾼级功能

1. 跳过操作

  • 说明: 对于完成的代码或版本不对应的代码, 可以设置跳过使之不参与测试执⾏
"""
跳过功能
"""
import pytestversion = 25 # 模拟软件版本号变量class TestDemo1(object):"""示例测试类"""def test_method1(self):"""测试⽅法"""print('测试⽅法1')# 语法: @pytest.mark.skipif(符合的条件, reason='跳过的原因')# 说明: 如果满⾜条件, 以下⽅法或测试类执⾏跳过, 不执⾏!# 注意: reason= 不能省略, 否则报错!# @pytest.mark.skipif(version >= 25, 'xxx') # 错误样例@pytest.mark.skipif(version >= 25, reason='当前版本不执⾏') # 
正确样例def test_method2(self):"""测试⽅法"""print('测试⽅法2')# 说明: 同样可以跳过测试类
@pytest.mark.skipif(version >= 25, reason='当前版本不执⾏')
class TestDemo2(object):"""示例测试类2"""def test_method(self):print('测试类2 -> 测试⽅法')if __name__ == '__main__':pytest.main(['-s', 'hm10_pytest_skip.py'])

2. 参数化操作

  • 说明: 与 UnitTest 框架不同, pytest 框架⾃带参数化功能, 调⽤对应⽅法并传⼊数据, 即可完成参数化实现

2.1 单个参数

"""
pytest 参数化功能: 单个参数
"""
import pytestclass TestDemo(object):"""示例测试类"""# 语法: @pytest.mark.parametrize('参数变量', ['数值1', '数值
2', ...])@pytest.mark.parametrize('name', ['⼩明', '⼩刚', '⼩红'])def test_method(self, name):"""测试⽅法"""print('获取的名字是:', name)if __name__ == '__main__':pytest.main(['-s', 'hm11_pytest_para1.py'])

2.2 多个参数

"""
pytest 参数化: 多个参数
"""
import pytestclass TestDemo(object):"""示例测试类"""# 语法: @pytest.mark.parametrize('参数1, 参数n', [(数据1-1, 数1-2), (数据2-1, 数据2-2), ...])# 注意:# 1. 多个参数必须置于同⼀个字符串内!# 2. 数据格式必须是: [(), ()] 或者 [[], []]# 扩展: 另⼀种写法# @pytest.mark.parametrize(('name', 'pwd'), [('admin', 
123456), ('test', 654321), ('xxx', 'yyy')])@pytest.mark.parametrize('name, pwd', [('admin', 123456), 
('test', 654321), ('xxx', 'yyy')])def test_method(self, name, pwd):"""测试⽅法"""print('账号:{} 密码:{}'.format(name, pwd))if __name__ == '__main__':pytest.main(['-s', 'hm12_pytest_para2.py'])

3. 扩展: 断⾔⽅法的使⽤

  • 说明: 与 UnitTest 框架不同的是, pytest 框架使⽤ Python ⾃带的断⾔⽅法实现断⾔操作的

3.1 Python ⾃带的断⾔⽅法

# 语法: assert 表达式
# 说明: 断⾔后接的表达式的结果为 Ture(断⾔通过), 为 False(断⾔失败)
# 预期相等:
assert 1 == 1
# 预期包含:
assert 'admin' in '欢迎 admin 归来!'

3.2 pytest 框架中使⽤断⾔

"""
pytest 断⾔
"""
import pytestdef add_func(num1, num2):"""加法函数"""return num1 + num2class TestDemo(object):"""示例测试类"""def test_method(self):"""加法测试⽅法"""# 调⽤被测函数result = add_func(1, 2)# 断⾔判断结果assert 4 == resultif __name__ == '__main__':pytest.main(['-s', 'hm14_pytest_assert.py'])

四、PO 设计模式

1. v0 版本

  • 特点: 对于同⼀个待测模块, 对应的测试代码步骤完全⼀致, 只有测试数据存在差异, 因此对于反复出现的相同逻辑的测试代码, 需要考虑通过封装的思路对⻬进⾏整理, 以提⾼测试脚本的编写效率.
  • 注意: 通过直接定位元素并操作元素的⽅式实现的⾃动化脚本, 已经算是 UI ⾃动化的实现形式了!

2. 账户不存在脚本

"""
账号不存在测试⽤例
"""
from time import sleep
from selenium import webdriverdriver = webdriver.Chrome()
driver.get('http://127.0.0.1/')
driver.maximize_window() # 窗⼝最⼤化
driver.implicitly_wait(10) # 隐式等待# 1. 点击⾸⻚的‘登录’链接,进⼊登录⻚⾯
driver.find_element_by_link_text('登录').click()# 2. 输⼊⼀个不存在的⽤户名
driver.find_element_by_id('username').send_keys('13811110001')
# 3. 输⼊密码
driver.find_element_by_id('password').send_keys('123456')
# 4. 输⼊验证码
driver.find_element_by_id('verify_code').send_keys('8888')
# 5. 点击登录按钮
driver.find_element_by_name('sbtbutton').click()# 6. 获取错误提示信息
# 获取元素⽂本值: 元素对象.text
msg = driver.find_element_by_class_name('layui-layercontent').text
print('错误信息为:',
msg)sleep(3)
driver.quit()

3. 密码错误脚本

"""
密码错误测试⽤例
"""
from time import sleep
from selenium import webdriverdriver = webdriver.Chrome()
driver.get('http://127.0.0.1/')
driver.maximize_window() # 窗⼝最⼤化
driver.implicitly_wait(10) # 隐式等待# 1. 点击⾸⻚的‘登录’链接,进⼊登录⻚⾯
driver.find_element_by_link_text('登录').click()# 2. 输⼊⽤户名
driver.find_element_by_id('username').send_keys('13800001111')
# 3. 输⼊错误密码
driver.find_element_by_id('password').send_keys('error')
# 4. 输⼊验证码
driver.find_element_by_id('verify_code').send_keys('8888')
# 5. 点击登录按钮
driver.find_element_by_name('sbtbutton').click()# 6. 获取错误提示信息
# 获取元素⽂本值: 元素对象.text
msg = driver.find_element_by_class_name('layui-layercontent').text
print('错误信息为:',
msg)sleep(3)
driver.quit()
http://www.xdnf.cn/news/3004.html

相关文章:

  • grafana/loki 设置日志保留时间
  • Cursor —— AI编辑器 使用详解
  • 【动态导通电阻】 GaN PiN二极管电导调制对动态 RON 的影响
  • 从Windows开发迁移到信创开发的指南:国产替代背景下的技术路径与实践
  • Webshell管理工具的流量特征
  • 桂链:使用Fabric的测试网络
  • 043-代码味道-循环依赖
  • LeetCode58_最后一个单词的长度
  • QT控件 参考Qt的PIMPL设计模式实现使用QWidget控件绘制3D饼状图表和3D柱状图表,使用QChartView绘制圆柱体图表
  • CORS跨域学习
  • opencv 模板匹配
  • [USACO08DEC] Hay For Sale S Java
  • React Native 太慢:kotlin-gradle-plugin-2.0.21-gradle76.jar 下载太慢
  • Code Complete代码大全20年纪念版附录书籍等
  • 归并排序排序总结
  • 某高端制造企业知识中枢升级,基于悦数 Graph RAG 打造工业级「故障排查最强大脑」
  • OceanBase数据库-学习笔记5-用户
  • 《系统分析师-第三阶段—总结(七)》
  • C++入门(缺省参数/函数/引用)
  • 组件轮播与样式结构重用实验
  • Linux《进程概念(中)》
  • 在Arduino U8g2库中显示中文的方法
  • 「Mac畅玩AIGC与多模态06」开发篇02 - 开发第一个知识库问答应用
  • 电流探头的创新应用与霍尔效应原理
  • word文档插入公式后行距变大怎么办?
  • 大模型入门
  • 码蹄集——进制输出、求最大公约数、最小公倍数
  • 【时时三省】(C语言基础)循环结构程序设计习题2
  • 如何从大规模点集中筛选出距离不小于指定值的点
  • C语言-指针(一)