Pytest框架测试

Pytest 是什么?

  • pytest 能够支持简单的单元测试和复杂的功能测试;
  • pytest 可以结合 Requests 实现接口测试; 结合 Selenium、Appium 实现自动化功能测试;
  • 使用 pytest 结合 Allure 集成到 Jenkins 中可以实现持续集成。
  • pytest 支持 315 种以上的插件;

为什么要选择 Pytest

  • 丰富的第三方插件
    • 报告
    • 多线程
    • 顺序控制

为什么要选择 Pytest

  • 简单灵活
  • # content of test_sample.py def inc(x):
  • return x + 1
  • def test_answer():
  • assert inc(3) == 5

为什么要选择 Pytest

  • 兼容 unittest
  • 定制化插件开发

Pytest 环境安装

  • 前提:本地已配置完成 Python 环境
  • 第一种方式 pip install pytest
  • 第二种方式 PyCharm 直接安装

运行第一个脚本

# content of test_sample.py def inc(x):

return x + 1 def test_answer():

assert inc(3) == 5

Pytest 有哪些格式要求?

  • 文件名
  • 方法/函数

Pytest 测试用例编写规则是什么?

类型规则
文件test_开头 或者 _test 结尾
Test 开头
方法/函数test_开头
注意:测试类中不可以添加__init__构造函数

Pycharm 默认测试执行器为Pytest

  1. 进入 Tools->Python Intergrated Tools
  2. 选择 Default test runner 为 pytest

用例结构

  • 三部分构成
    • 用例名称
    • 用例步骤
    • 用例断言

测试用例示例

def test_XXX(self):

# 测试步骤1

# 测试步骤2

# 断言 实际结果 对比 预期结果

assert ActualResult == ExpectedResult

类级别的用例示例

class TestXXX:
    def setup(self):
        # 资源准备
        pass

    def teardown(self):
        # 资源销毁
        pass

    def test_XXX(self):
        # 测试步骤1
        # 测试步骤2
        # 断言  实际结果 对比 预期结果
        assert ActualResult == ExpectedResult

断言(assert),是一种在程序中的一阶逻辑(如:一个结果为真或假的逻辑判断式),目的为了表示与验证软件开发者预期的结果。当程序执行到断言的位置时,对应的断言应该为真。若断言不为真时,程序会中止执行,并给出错误信息。

断言的用法

  • 断言写法
    • assert <表达式>
    • assert <表达式>,<描述>

assert <bool expression>;   

assert <bool expression> : <message>; 

  • 第一种:assert <表达式>
  • 第二种:assert <表达式>,<描述>

def test_a():
    assert True

def test_b():
    a = 1
    b = 1
    c = 2
    assert a + b == c, f"{a}+{b}=={c}, 结果为真"

  • assert <表达式>

def test_c():
    a = 1
    b = 1
    c = 2
    assert 'abc' in "abcd"

import sys
def test_plat():
    assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"

测试装置介绍

类型规则
setup_module/teardown_module全局模块级
setup_class/teardown_class类级,只在类中前后运行一次
setup_function/teardown_function函数级,在类外
setup_method/teardown_method方法级,类中的每个方法执行前后
setup/teardown在类中,运行在调用方法的前后(重点)

参数化

  • 通过参数的方式传递数据,从而实现数据和脚本分离。
  • 并且可以实现用例的重复生成与执行。

参数化应用场景

  • 测试登录场景
    • 测试登录成功,登录失败(账号错误,密码错误)
    • 创建多种账号: 中⽂文账号,英⽂文账号
  • 普通测试用例方法
    • Copy 多份代码 or 读⼊入参数?
    • 一次性执⾏多个输⼊入参数

def test_param_login_ok():
    # 登录成功
    username = "right"
    password = "right"
    login(username,password)

def test_param_login_fail():
    # 登录失败
    username = "wrong"
    password = "wrong"
    login(username,password)
 

参数化实现方案

  • pytest 参数化实现方法
  • 装饰器:@pytest.mark.parametrize

@pytest.mark.parametrize("username,password",[["right","right"], ["wrong","wrong"]])
def test_param(username,password):
    login(username,password)

Mark:参数化测试函数使用

  • 单参数
  • 多参数
  • 用例重命名
  • 笛卡尔积

参数化:单参数情况

  • 单参数,可以将数据放在列表中

search_list = ['appium','selenium','pytest']

@pytest.mark.parametrize('name',search_list)
def test_search(name):
    assert name in search_list

参数化:多参数情况

  • 将数据放在列表嵌套元组中
  • 将数据放在列表嵌套列表中

# 数据放在元组中
@pytest.mark.parametrize("test_input,expected",[
    ("3+5",8),("2+5",7),("7+5",12)
])
def test_mark_more(test_input,expected):
    assert eval(test_input) == expected
# 数据放在列表中
@pytest.mark.parametrize("test_input,expected",[
    ["3+5",8],["2+5",7],["7+5",12]
])
def test_mark_more(test_input,expected):
    assert eval(test_input) == expected

参数化:用例重命名-添加 ids 参数

  • 通过ids参数,将别名放在列表中

@pytest.mark.parametrize("test_input,expected",[
    ("3+5",8),("2+5",7),("7+5",12)
],ids=['add_3+5=8','add_2+5=7','add_3+5=12'])
def test_mark_more(test_input,expected):
    assert eval(test_input) == expected

参数化:用例重命名-添加 ids 参数(中文)

@pytest.mark.parametrize("test_input,expected",[
    ("3+5",8),("2+5",7),("7+5",12)
],ids=["3和5相加","2和5相加","7和5相加"])
def test_mark_more(test_input,expected):
    assert eval(test_input) == expected
    
# 创建conftest.py 文件 ,将下面内容添加进去,运行脚本
def pytest_collection_modifyitems(items):
    """
    测试用例收集完成时,将收集到的用例名name和用例标识nodeid的中文信息显示在控制台上
    """
    for i in items:
        i.name=i.name.encode("utf-8").decode("unicode_escape")
        i._nodeid=i.nodeid.encode("utf-8").decode("unicode_escape")

参数化:笛卡尔积

  • 两组数据
    • a=[1,2,3]
    • b=[a,b,c]
  • 对应有几种组合形势 ?
    • (1,a),(1,b),(1,c)
    • (2,a),(2,b),(2,c)
    • (3,a),(3,b),(3,c)

@pytest.mark.parametrize("b",["a","b","c"])
@pytest.mark.parametrize("a",[1,2,3])
def test_param1(a,b):
    print(f"笛卡积形式的参数化中 a={a} , b={b}")

Mark:标记测试用例

  • 场景:只执行符合要求的某一部分用例 可以把一个web项目划分多个模块,然后指定模块名称执行。
  • 解决: 在测试用例方法上加 @pytest.mark.标签名
  • 执行: -m 执行自定义标记的相关用例
    • pytest -s test_mark_zi_09.py -m=webtest
    • pytest -s test_mark_zi_09.py -m apptest
    • pytest -s test_mark_zi_09.py -m "not ios"

pytest 设置跳过、预期失败

Mark:跳过(Skip)及预期失败(xFail)

  • 这是 pytest 的内置标签,可以处理一些特殊的测试用例,不能成功的测试用例
  • skip - 始终跳过该测试用例
  • skipif - 遇到特定情况跳过该测试用例
  • xfail - 遇到特定情况,产生一个“期望失败”输出

Skip 使用场景

  • 调试时不想运行这个用例
  • 标记无法在某些平台上运行的测试功能
  • 在某些版本中执行,其他版本中跳过
  • 比如:当前的外部资源不可用时跳过
    • 如果测试数据是从数据库中取到的,
    • 连接数据库的功能如果返回结果未成功就跳过,因为执行也都报错
  • 解决 1:添加装饰器
    • @pytest.mark.skip
    • @pytest.mark.skipif
  • 解决 2:代码中添加跳过代码
    • pytest.skip(reason)

xfail 使用场景

  • 与 skip 类似 ,预期结果为 fail ,标记用例为 fail
  • 用法:添加装饰器@pytest.mark.xfail

运行多条用例

  • 运行 某个/多个 用例包
  • 运行 某个/多个 用例模块
  • 运行 某个/多个 用例类
  • 运行 某个/多个 用例方法

运行多条用例方式

  • 执行包下所有的用例:pytest/py.test [包名]
  • 执行单独一个 pytest 模块:pytest 文件名.py
  • 运行某个模块里面某个类:pytest 文件名.py::类名
  • 运行某个模块里面某个类里面的方法:pytest 文件名.py::类名::方法名

运行结果分析

  • 常用的:fail/error/pass
  • 特殊的结果:warning/deselect(后面会讲)

命令行参数-使用缓存状态

  • --lf(--last-failed) 只重新运行故障。
  • --ff(--failed-first) 先运行故障然后再运行其余的测试

命令行参数 - 常用命令行参数

—help 
-x   用例一旦失败(fail/error),就立刻停止执行
--maxfail=num 用例达到
-m  标记用例
-k  执行包含某个关键字的测试用例
-v 打印详细日志
-s 打印输出日志(一般-vs一块儿使用)
—collect-only(测试平台,pytest 自动导入功能 )

python 代码执行 pytest

  • 使用 main 函数
  • 使用 python -m pytest 调用 pytest(jenkins 持续集成用到)

Python 代码执行 pytest - main 函数

if __name__ == '__main__':
    # 1、运行当前目录下所有符合规则的用例,包括子目录(test_*.py 和 *_test.py)
    pytest.main()
    # 2、运行test_mark1.py::test_dkej模块中的某一条用例
    pytest.main(['test_mark1.py::test_dkej','-vs'])
    # 3、运行某个 标签
    pytest.main(['test_mark1.py','-vs','-m','dkej'])

运行方式
  `python test_*.py `

常用的异常处理方法

  • try…except
  • pytest.raises()

异常处理方法 try …except

try:
    可能产生异常的代码块
except [ (Error1, Error2, ... ) [as e] ]:
    处理异常的代码块1
except [ (Error3, Error4, ... ) [as e] ]:
    处理异常的代码块2
except  [Exception]:
    处理其它异常

异常处理方法 pytest.raise()

  • 可以捕获特定的异常
  • 获取捕获的异常的细节(异常类型,异常信息)
  • 发生异常,后面的代码将不会被执行

pytest.raise() 用法

异常处理方法 pytest.raise()

def test_raise():
    with pytest.raises(ValueError, match='must be 0 or None'):
        raise ValueError("value must be 0 or None")

def test_raise1():
    with pytest.raises(ValueError) as exc_info:
        raise ValueError("value must be 42")
    assert exc_info.type is ValueError
    assert exc_info.value.args[0] == "value must be 42"

Pytest 结合数据驱动 YAML

数据驱动

  • 什么是数据驱动?

    • 数据驱动就是数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变。简单来说,就是参数化的应用。数据量小的测试用例可以使用代码的参数化来实现数据驱动,数据量大的情况下建议大家使用一种结构化的文件(例如 yaml,json 等)来对数据进行存储,然后在测试用例中读取这些数据。
  • 应用:

    • App、Web、接口自动化测试
    • 测试步骤的数据驱动
    • 测试数据的数据驱动
    • 配置的数据驱动

yaml 文件介绍

  • 对象:键值对的集合,用冒号 “:” 表示
  • 数组:一组按次序排列的值,前加 “-”
  • 纯量:单个的、不可再分的值
    • 字符串
    • 布尔值
    • 整数
    • 浮点数
    • Null
    • 时间
    • 日期

# 编程语言
languages:
  - PHP
  - Java
  - Python
book:
  Python入门: # 书籍名称
    price: 55.5
    author: Lily
    available: True
    repertory: 20
    date: 2018-02-17
  Java入门:
    price: 60
    author: Lily
    available: False
    repertory: Null
    date: 2018-05-11

yaml 文件使用

  • 查看 yaml 文件
    • pycharm
    • txt 记事本
  • 读取 yaml 文件
    • 安装:pip install pyyaml
    • 方法:yaml.safe_load(f)
    • 方法:yaml.safe_dump(f)

import yaml
file_path = './my.yaml'
with open(file_path, 'r', encoding='utf-8') as f:
    data = yaml.safe_load(f)

工程目录结构

  • data 目录:存放 yaml 数据文件
  • func 目录:存放被测函数文件
  • testcase 目录:存放测试用例文件

# 工程目录结构
.
├── data
│   └── data.yaml
├── func
│   ├── __init__.py
│   └── operation.py
└── testcase
    ├── __init__.py
    └── test_add.py

测试准备

  • 被测对象:operation.py
  • 测试用例:test_add.py
  • 测试数据:data.yaml

# operation.py 文件内容
def my_add(x, y):
    result = x + y
    return result
# test_add.py 文件内容
class TestWithYAML:
  @pytest.mark.parametrize('x,y,expected', [[1, 1, 2]])
  def test_add(self, x, y, expected):
    assert my_add(int(x), int(y)) == int(expected)
# data.yaml 文件内容
-
  - 1
  - 1
  - 2
-
  - 3
  - 6
  - 9
-
  - 100
  - 200
  - 300

Pytest 数据驱动结合 yaml 文件

# 读取yaml文件
def get_yaml():
    """
    获取json数据
    :return: 返回数据的结构:[[1, 1, 2], [3, 6, 9], [100, 200, 300]]
    """
    with open('../datas/data.yaml', 'r') as f:
        data = yaml.safe_load(f)
        return data

Pytest 结合数据驱动 Excel

读取 Excel 文件

  • 第三方库

    • xlrd
    • xlwings
    • pandas
  • openpyxl

    • 官方文档: https://openpyxl.readthedocs.io/en/stable/

openpyxl 库的安装

  • 安装:pip install openpyxl
  • 导入:import openpyxl

openpyxl 库的操作

  • 读取工作簿

  • 读取工作表

  • 读取单元格

import openpyxl

# 获取工作簿
book = openpyxl.load_workbook('../data/params.xlsx')

# 读取工作表
sheet = book.active

# 读取单个单元格
cell_a1 = sheet['A1']
cell_a3 = sheet.cell(column=1, row=3)  # A3

# 读取多个连续单元格
cells = sheet["A1":"C3"]

# 获取单元格的值
cell_a1.value

工程目录结构

  • data 目录:存放 excel 数据文件

  • func 目录:存放被测函数文件

  • testcase 目录:存放测试用例文件

# 工程目录结构
.
├── data
│   └── params.excel
├── func

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/664237.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VUE项目导出excel

导出excel主要可分为以下两种&#xff1a; 1. 后端主导实现 流程&#xff1a;前端调用到导出excel接口 -> 后端返回excel文件流 -> 浏览器会识别并自动下载 场景&#xff1a;大部分场景都有后端来做 2. 前端主导实现 流程&#xff1a;前端获取要导出的数据 -> 把常规数…

跨平台开发:浅析uni-app及其他主流APP开发方式

随着智能手机的普及&#xff0c;移动应用程序&#xff08;APP&#xff09;的需求不断增长。开发一款优秀的APP&#xff0c;不仅需要考虑功能和用户体验&#xff0c;还需要选择一种适合的开发方式。随着技术的发展&#xff0c;目前有多种主流的APP开发方式可供选择&#xff0c;其…

亚马逊新店铺视频怎么上传?视频验证失败怎么办?——站斧浏览器

亚马逊新店铺视频怎么上传&#xff1f; 登录亚马逊卖家中心&#xff1a;首先&#xff0c;卖家需要登录亚马逊卖家中心。在登录后&#xff0c;可以点击左侧导航栏上的“库存”选项&#xff0c;然后选择“新增或管理商品”。 选择商品&#xff1a;接下来&#xff0c;在“新增或…

【Vue】3-2、组合式 API

一、setup 选项 <script> export default {/*** 1、setup 执行时机早于 beforeCreate* 2、setup 中无法获取 this* 3、数据和函数需要在 setup 最后 return&#xff0c;才能在模板中使用* 4、可以通过 setup 语法糖简化代码*/setup(){// console.log(setup function, thi…

云服务器安全组、防火墙、端口问题,结合telnet解决项目部署无法访问

无论是运维还是后台亲自操刀在云服务器上部署项目&#xff0c;往往会遇到项目部署上去了&#xff0c;也确定项目正常运行&#xff0c;但还是没法访问的问题。 如果没有经验的小伙伴&#xff0c;很容易陷入疑惑的状态&#xff0c;无从下手解决。 其实这涉及到云平台安全组、服…

计算机毕业设计社区居民服务管理系统SSM

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; vue mybatis Maven mysql5.7或8.0等等组成&#xff0c;B…

25.云原生之ArgoCD-app of apps模式

文章目录 app of apps 模式介绍app如何管理apphelm方式管理kustomize方式管理 app of apps 模式介绍 通过一个app来管理其他app&#xff0c;当有多个项目要发布创建多个app比较麻烦&#xff0c;此时可以创建一个管理app&#xff0c;管理app创建后会创建其他app。比较适合项目环…

【Power Platform】实现对SharePoint文档库中上传的文件进行审批

这次要分享的案例还是来自于我们客户的一个新需求。 我们这个客户主要是在使用SharePoint的List来搭建申请单&#xff0c;然后对申请单进行审批&#xff0c;但由于我们之前给客户提出的生成PDF打印件的方案&#xff0c;是需要先在SharePoint或OneDrive中放一个文档模板的&…

2024 高级前端面试题之 HTTP模块 「精选篇」

该内容主要整理关于 HTTP模块 的相关面试题&#xff0c;其他内容面试题请移步至 「最新最全的前端面试题集锦」 查看。 HTTP模块精选篇 1. HTTP 报文的组成部分2. 常见状态码3. 从输入URL到呈现页面过程3.1 简洁3.2 详细 4. TCP、UDP相关5. HTTP2相关6. https相关7. WebSocket的…

计算存储设备(Computational Storage Drive, CSD)

随着云计算、企业级应用以及物联网领域的飞速发展&#xff0c;当前的数据处理需求正以前所未有的规模增长&#xff0c;以满足存储行业不断变化的需求。这种增长导致网络带宽压力增大&#xff0c;并对主机计算资源&#xff08;如内存和CPU&#xff09;造成极大负担&#xff0c;进…

网络协议与攻击模拟_14DNS欺骗

DNS欺骗就是利用某种方式将我们访问的域名解析到其他服务器上&#xff0c;从而使得我们无法正常访问到原本我们想要访问的网站。 一、DNS欺骗过程 首先在windows server 2016虚拟机上搭建网站服务&#xff0c;kali作为攻击机从而实现中间人攻击&#xff0c;使用ettercap工具的…

构造函数 | 初始化列表 | 拷贝构造 | 赋值运算符重载

文章目录 1.类的6个默认成员函数2.构造函数2.1基本概念和用法2.2初始化列表2.3explicit关键字 3.拷贝构造函数4.重载赋值运算符 1.类的6个默认成员函数 如果定义一个空类&#xff0c;其实并不是什么都没有&#xff0c;编译器会默认生成6个默认的成员函数&#xff01;默认成员函…

从源代码看Chrome 版本号

一直以来都是用Chrome 浏览器&#xff0c;但是看到Chrome 点分4 组数据的表达方式&#xff0c;总是感觉怪怪的&#xff0c;遂深入源代码了解她的版本号具体表示的内容 chrome 浏览器中显示的版本号 源代码中的版本号标识 版本号文件位于 chrome/VERSION &#xff0c; 看到源代…

网络流数据集处理(深度学习数据处理基础)

一、数据集处理 处理数据集是一个文件夹 一个文件夹处理的&#xff0c;将原网络流数据集 放入一个文件夹 处理转换成 Json文件。&#xff08;数据预处理&#xff09;然后将这些文件处理成目标文件格式 再分割成训练集和测试集。每次运行只会处理一个文件夹。 运行train.py 导入…

Windows10 安装 OpenSSH 配置 SFTP服务器

1、下载 https://github.com/PowerShell/Win32-OpenSSH/releases 2、默认安装 3、创建用户 4、修改配置文件 C:\ProgramData\ssh\sshd_config# 最后一行后面加入 ForceCommand internal-sftp# 设置用户登录后默认目录 Match User sftpuser ChrootDirectory C:\SFTP# Disable…

进程信号-

一.信号概念 信号是进程之间事件异步通知的一种方式&#xff0c;属于软中断。 二.信号的产生 1.通过键盘进行信号的产生。&#xff08;1-31多数都是杀掉进程&#xff09; &#xff08;ctrl c&#xff1a;向前台进程发送2号信号&#xff0c;杀掉进程&#xff09; &#xff0…

基于JAVA的宠物管理系统

技术架构&#xff1a; Servlet JSP MySQL 有需要该项目的小伙伴可以私信我你的Q。 功能介绍&#xff1a; 系统主要分为前台和后台两大模块 前台主要由用户体验使用: 用户登录 注册 查找商品 商品类别等功能导航&#xff1b; 后台…

Github 2024-02-03 开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2024-02-03统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目6C项目1TypeScript项目1JavaScript项目1PowerShell项目1Rust项目1 MLflow: 机器学习生命周期平台 …

AI监控+智能充电桩系统如何缓解新能源汽车充电难问题

在新能源汽车行业的快速发展中&#xff0c;充电桩作为重要的配套设施&#xff0c;其建设和发展至关重要。随着新能源汽车销量的增长&#xff0c;补能需求也日益迫切&#xff0c;这为充电桩行业的发展提供了巨大的机遇。然而&#xff0c;充电桩行业在快速发展的同时&#xff0c;…

[云顶数模]2024美赛CEF题成品参考论文+配套数据集+可执行代码+运行结果图

E题社区抗灾能力综合评估与决策模型研究 摘要&#xff1a;社区抗灾能力的提升对于灾害风险管理至关重要。本研究基于机器学 习方法&#xff0c;构建了社区抗灾能力预测模型&#xff0c;以评估社区在灾害事件中的表现。首先&#xff0c; 我们采用梯度提升树模型对社区基础设施、…