python 自动化测试 pytest 的使用

news/2024/4/27 6:06:22/文章来源:https://blog.csdn.net/m0_53918927/article/details/129207334

pytest 是一款以python为开发语言的第三方测试,主要特点如下:

  1.  比自带的 unittest 更简洁高效,兼容 unittest框架

  2. 支持参数化

  3. 可以更精确的控制要测试的测试用例

  4. 丰富的插件,已有300多个各种各样的插件,也可自定义扩展,如pytest-selenium、pytest-html、pytest-rerunfailures、pytes-xdish

  5. 可很好的和CI工具结合

安装

pip install pytest

测试用例编写规则

  1. 测试文件以test_开头 或者 _test结尾

  2. 测试类以Test开头,并且不能带有 init 方法

  3. 测试文件以 test_开头

  4. 断言使用基本的 assert 即可

pytest会递归查找当前目录及子目录下所有 以test_开始 或者 _test结尾的python脚本,执行其中符合规则的函数和方法,不需要显示调用

运行命令:(cmd进入用例所在目录)

  1. pytest folder_name ======》直接运行文件夹内符合规则的所有用例
  2. pytest test_file.py ======》执行某个py文件中的用例
  3. pytest test_file.py::test_func ======》执行模块内的某个函数(节点运行)
  4. pytest test_file.py::TestClass::test_method ======》执行模块内测试类的某个方法(节点运行)
  5. pytest test_file.py::TestClass ======》执行模块内某个测试类(节点运行)
  6. pytest test_file.py::TestClass test_file2.py::test_mothod ======》多节点运行,中间用空格隔开
  7. pytest -k pass ======》匹配用例名称的表达式,含有“pass”的被执行,其他的deselected
  8. pytest -k "pass or fail" ======》组合匹配,含有“pass” 和 “fail”的被执行
  9. pytest -k "not pass" ======》排除运行,不含“pass”的被执行
  10. pytest -m finished ======》标记表达式,运行用@pytest.mark.finished 标记的用例
  11. pytest -m "finished and not merged" ======》多个标记逻辑匹配,运行含有finished 不含 merged标记的用例
  12. pytest -v ======》运行时显示详细信息
  13. pytest -s ======》显示打印消息
  14. pytest -x  ======》遇到错误就停止运行
  15. pytest -x --maxfail=2 ======》遇到两个错误就停止运行
  16. pytest --setup-show ======》跟踪固件运行
  17. pytest -v --reruns 5 --reruns-delay 1 ======》运行失败的用例间隔1s重新运行5次  pip install pytest-rerunfailures
  18. pytest ======》多条断言,报错后,后面的依然执行, pip install pytest-assume,断言 pytest.assume(2==4)
  19. pytest -n 3 ======》3个cpu并行执行测试用例,需保证测试用例可随机执行, pip install pytest-xdist分布式执行插件,多个cpu或主机执行
  20. pytest -v -n auto ======》自动侦测系统里cpu的数目
  21. pytest --count=2 ======》重复运行测试 pip install pytest-repeat
  22. pytest --html=./report/report.html ======》生成报告,此报告中css是独立的,分享时会丢失样式,pip install pytest-html
  23. pytest --html=report.html --self-containd-html ======》合并css到html报告中,除了passed所有行都被展开
  24. pytest --durations=10 ======》获取最慢的10个用例的执行耗时

用例执行顺序控制

pytest 用例执行顺序默认是按字母顺序去执行,要控制执行顺序,需要安装插件 pytest-ordering:pip install pytest-ordering

在测试方法上加上装饰器:

@pytest.mark.last 最后一个执行

@pytest.mark.run(order=n) n=1则是第一个执行

Mark

标签的使用方法:

注册标签名 / 内置标签---> 在测试用例  / 测试类 / 模块文件 前面加上 @pytest.mark.标签名

注册方法:

1. 在conftest.py 文件中添加代码

# 单个标签文件内容
def pytest_configure(config):config.addinivalue_line("markers", "demo:demo标签名称")# 多个标签文件内容
def pytest_configure(config):marker_list = ["p0:p0级别用例", "p1:p1级别用例", "p2:p2级别用例"] # 标签名称for markers in marker_list:config.addinivalue_line("markers", markers)

2. 项目中添加pytest.ini配置文件

[pytest]
markers = p0:p0级别用例p1:p1级别用例p2:p2级别用例

使用方法:

import pytest@pytest.mark.p0
def test_mark01():print("函数级别的mark_p0")@pytest.mark.p1
def test_mark02():print("函数级别的mark_p1")@pytest.mark.P2
class TestDemo:def test_mark03(self):print("mark_p2")def test_mark04(self):print("mark_p2")

运行方式:

1. 命令行运行

pytest -m "p0 and p1"

2. 文件运行

pytest.main(["-m", "P0", "--html=report.html"])

内置标签:

参数化:@pytest.mark.parametrize(argnames, argvalues)

无条件跳过用例:@pytest.mark.skip(reason="xxx")

有条件跳过用例:@pytest.mark.skipif(version < 0.3, reason = "not supported until 0.3")

预测执行失败进行提示标记:@pytest.mark.xfail(version < 0.3, reason = "not supported until 0.3"),运行结果为X(通过xpassed,失败xfailed)

# 参数化
import hashlib@pytest.mark.parametrize("x", list(range(10)))
def test_somethins(x):time.sleep(1)@pytest.mark.parametrize("passwd",["123456", "abcdefgfs", "as52345fasdf4"])
def test_passwd_length(passwd):assert len(passwd) >= 8@pytest.mark.parametrize('user, passwd',[('jack', 'abcdefgh'),('tom', 'a123456a')])
def test_passwd_md5(user, passwd):db = {'jack': 'e8dc4081b13434b45189a720b77b6818','tom': '1702a132e769a623c1adb78353fc9503'}assert hashlib.md5(passwd.encode()).hexdigest() == db[user]# 如果觉得每组测试的默认参数显示不清晰,可以使用 pytest.param 的 id 参数进行自定义
@pytest.mark.parametrize("user, passwd",[pytest.param("jack", "abcdefgh", id = "User<Jack>"),pytest.param("tom", "a123456a", id = "User<Tom>")])
def test_passwd_md5_id(user, passwd):db = {'jack': 'e8dc4081b13434b45189a720b77b6818','tom': '1702a132e769a623c1adb78353fc9503'}assert hashlib.md5(passwd.encode()).hexdigest() == db[user]

Fixture

固件:是一些函数,pytest会在执行函数之前或者之后加载运行它们,相当于预处理和后处理。

fixture的目的是提供一个固定基线,在该基线上测试可以可靠地、重复的执行。

  1. 名称:默认为定义时的函数名,可以通过 @pytest.fixture(name="demo") 给fixture重命名
  2. 定义:在固件函数定义前加上@pytest.fixture();fixture是有返回值的,没return则返回None
  3. 使用:作为参数、使用usefixtures、自动执行(定义时指定autouse参数)
    • def test_demo(fixture_func_name)
    • @pytest.mark.usefixtures("fixture_func_name1", "fixture_func_name2") 标记函数或者类
  4. 预处理和后处理:用yield关键词,yield之前的代码是预处理,之后的是后处理
  5. 作用域:通过scope参数控制作用域
    • function:函数级,每个测试函数都会执行一次(默认)
    • class:类级别,每个测试类执行一次,所有方法都共享这个fixture
    • module:模块级别,每个模块.py执行一次,模块中所有测试函数、类方法 或者 其他fixture 都共享这个fixture
    • session:会话级别,每次会话只执行一次,一次会话中所有的函数、方法都共享这个fixture
  6. 集中管理:使用文件conftest.py 集中管理,在不同层级定义,作用于在其所在的目录和子目录,pytest会自动调用

scope、yield、auto的使用

# scope、yield、auto使用
@pytest.fixture(scope = "function", autouse=True)
def function_scope():pass@pytest.fixture(scope = "module", autouse=True)
def module_scope():pass@pytest.fixture(scope = "session")
def session_scope():pass@pytest.fixture(scope = "class", autouse=True)
def class_scope():passimport timeDATE_FORMAT = '%Y-%m-%d %H:%M:%S'@pytest.fixture(scope='session', autouse=True)
def timer_session_scope():start = time.time()print('\nsession start: {}'.format(time.strftime(DATE_FORMAT, time.localtime(start))))yieldfinished = time.time()print('\nsession finished: {}'.format(time.strftime(DATE_FORMAT, time.localtime(finished))))print('session Total time cost: {:.3f}s'.format(finished - start))def test_1():time.sleep(1)def test_2():time.sleep(2)'''
执行命令:pytest --setup-show -s
固件执行结果:
test_pytest_study.py
session start: 2020-04-16 17:29:02SETUP    S timer_session_scopeSETUP    M module_scopeSETUP    C class_scopeSETUP    F function_scopetest_pytest_study.py::test_3 (fixtures used: class_scope, function_scope, module_scope, timer_session_scope).TEARDOWN F function_scopeTEARDOWN C class_scopeSETUP    C class_scopeSETUP    F function_scopetest_pytest_study.py::test_4 (fixtures used: class_scope, function_scope, module_scope, timer_session_scope).TEARDOWN F function_scopeTEARDOWN C class_scopeTEARDOWN M module_scope
session finished: 2020-04-16 17:29:05
session Total time cost: 3.087sTEARDOWN S timer_session_scope'''

使用文件conftest.py 集中管理

# conftest.py
# conding=utf-8
import pytest@pytest.fixture()
def postcode():print("执行postcode fixture")return "010"
# test_demo.py
# coding=utf-8
import pytestclass TestDemo():def test_postcode(self, postcode):assert postcode == "010"if __name__=="__main__":pytest.main(["--setup-show", "-s", "test_demo.py"])
python test_demo.py
执行过程:
test_demo.py 执行postcode fixtureSETUP    F postcodetest_demo.py::TestDemo::test_postcode (fixtures used: postcode).TEARDOWN F postcode
# 如果整个文件都用一个fixture,可以用pytestmark标记
pytestmark = pytest.mark.usefixtures("login")

fixture参数化

固件参数化需要使用pytest内置的固件request,并通过 request.param 获取参数。

# test_demo.py
@pytest.fixture(params=[("user1", "passwd1"),("user2", "passwd2")])
def param(request):return request.param@pytest.fixture(autouse=True)
def login(param):print("\n登录成功 %s %s" %param)yieldprint("\n退出成功 %s %s" %param)def test_api():assert 1 == 1'''
pytest -s -v test_demo.py
运行结果:
test_demo.py::test_api[param0]
登录成功 user1 passwd1
PASSED
退出成功 user1 passwd1test_demo.py::test_api[param1]
登录成功 user2 passwd2
PASSED
退出成功 user2 passwd2
'''

assert

assert "h" in "hello"
assert 3==4
assert 3!=4
assert f()==4
assert 5>6
assert not xx
assert {"0", "1", "2"} == {"0", "1", "2"}

最后:下方这份完整的软件测试视频学习教程已经整理上传完成,朋友们如果需要可以自行免费领取 【保证100%免费】

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

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

相关文章

【JDK8新特性之Stream流-Stream结果收集案例实操】

一.JDK8新特性之Stream流-Stream结果收集以及案例实操 二.Stream结果收集(collect函数)-实例实操 2.1 结果收集到集合中 /*** Stream将结果收集到集合中以及具体的实现 collect*/Testpublic void test01(){// 收集到List中 接口List<Integer> list Stream.of(1, 2, 3…

代码随想录【Day23】| 669. 修剪二叉搜索树、108. 将有序数组转换为二叉搜索树、538. 把二叉搜索树转换为累加树

669. 修剪二叉搜索树 题目链接 题目描述&#xff1a; 给定一个二叉搜索树&#xff0c;同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[L, R]中 (R>L) 。你可能需要改变树的根节点&#xff0c;所以结果应当返回修剪好的二叉搜索树的新…

Git ---- GitHub 操作

Git ---- GitHub 操作1. 创建远程仓库2. 远程仓库操作1. 创建爱你远程仓库别名2. 推送本地分支到远程仓库3. 克隆远程仓库到本地4. 邀请加入团队5. 拉取远程库内容3. 跨团队协作4. SSH 免密登录GitHub 网址&#xff1a;https://github.com/ Ps&#xff1a;全球最大同性交友网站…

makdown模版参考

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…

RK系列(RK3568) i2s 音频输入 麦克风驱动

平台&#xff1a;Android12SOC&#xff1a;RK3568外围芯片&#xff1a;XS9922i2s简介&#xff1a;从上图看I2s主要的线有&#xff1a;SDO SCLK LRCK MCLK I2S协议只定义三根信号线&#xff1a;串行时钟信号SCLK(BCLK)、数据信号SD和左右声道选择信号WS。&#xff08;1&#xff…

Leetcode力扣秋招刷题路-0103

从0开始的秋招刷题路&#xff0c;记录下所刷每道题的题解&#xff0c;帮助自己回顾总结 103. 二叉树的锯齿形层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此…

注意力机制详解系列(一):注意力机制概述

&#x1f468;‍&#x1f4bb;作者简介&#xff1a; 大数据专业硕士在读&#xff0c;CSDN人工智能领域博客专家&#xff0c;阿里云专家博主&#xff0c;专注大数据与人工智能知识分享。 &#x1f389;专栏推荐&#xff1a; 目前在写CV方向专栏&#xff0c;更新不限于目标检测、…

SSM+HTML搭建(小白教学)

最近做项目,觉得还是有意义记录以下前后端框架是怎么搭建的,今天给大家介绍介绍SSM:SpringBootSpringMVCMyBatis后端搭建:SpringBoot快速搭建的网站(Spring Initializr)选择创建之后,会下载到一个zip压缩包,对压缩包进行解压(包地址一般选择后端项目的放的文件夹中)用idea打开项…

上岸16K,薪资翻倍,在华为外包做测试是一种什么样的体验····

现在回过头看当初的决定&#xff0c;还是正确的&#xff0c;自己转行成功&#xff0c;现在进入了华为外包测试岗&#xff0c;脱离了工厂生活&#xff0c;薪资也翻了一倍不止。 我17年毕业于一个普通二本学校&#xff0c;电子信息工程学院&#xff0c;是一个很不出名的小本科。…

字符串匹配--strstr函数的模拟实现思路和代码

一&#xff0c;strstr函数 原型&#xff1a; const char * strstr ( const char * str1, const char * str2 );char * strstr ( char * str1, const char * str2 ); strstr是一个字符串匹配函数&#xff0c;在str1中去寻找str2&#xff0c;如果找到&#xff0c;返回str2在…

Tapdata Connector 实用指南:实时数仓场景之数据实时同步至 ClickHouse

【前言】作为中国的 “Fivetran/Airbyte”, Tapdata 是一个以低延迟数据移动为核心优势构建的现代数据平台&#xff0c;内置 60 数据连接器&#xff0c;拥有稳定的实时采集和传输能力、秒级响应的数据实时计算能力、稳定易用的数据实时服务能力&#xff0c;以及低代码可视化操作…

Tina_Linux_系统软件 开发指南

Tina_Linux_系统软件 开发指南 1 概述 编写目的&#xff1a;本文档作为Allwinner Tina Linux系统平台开发指南&#xff0c;旨在帮助软件开发工程师、技术支持工程师快速上手&#xff0c;熟悉Tina Linux系统的开发及调试流程。 适用范围&#xff1a;Tina Linux v3.5及以上版本…

博客管理系统--项目说明

项目体验地址&#xff08;账号&#xff1a;123&#xff0c;密码&#xff1a;123&#xff09;http://120.53.20.213:8080/blog_system/login.html项目码云Gitee地址&#xff1a;https://gitee.com/GoodManSS/project/tree/master/blog_system&#xff08;一&#xff09;准备工作…

常见前端基础面试题(HTML,CSS,JS)(三)

JS 中如何进行数据类型的转换&#xff1f; 类型转换可以分为两种&#xff0c;隐性转换和显性转换 显性转换 主要分为三大类&#xff1a;数值类型、字符串类型、布尔类型 三大类的原始类型值的转换规则我就不一一列举了 数值类型&#xff08;引用类型转换&#xff09; Numbe…

什么是SSL端口?HTTPS配置技术指南

安全套接字层&#xff08;SSL&#xff09;是负责互联网连接的数据身份验证和加密的技术。它加密在两个系统之间&#xff08;通常在服务器和客户端之间&#xff09;之间通过互联网发送的数据&#xff0c;使其保持私密。随着在线隐私的重要性日益增加&#xff0c;您应该熟悉SSL端…

「RISC-V Arch」SBI 规范解读(上)

术语 SBI&#xff0c;Supervisor Binary Interface&#xff0c;管理二进制接口 U-Mode&#xff0c;User mode&#xff0c;用户模式 S-Mode&#xff0c;Supervisor mode&#xff0c;监督模式 VS-Mode&#xff0c;Virtualization Supervisor mode&#xff0c;虚拟机监督模式 …

电商共享购模式,消费增值返利,app开发

在当今以市场需求为主导的数字经济时代&#xff0c;消费者需求呈现出精细化管理和多元化的特性&#xff0c;目标市场日渐完善&#xff0c;另外在大数据技术迅速进步和运用的驱动下&#xff0c;总体行业的发展节奏感也在不断加速。因而&#xff0c;企业需要建立一套灵活多变的经…

HyperGBM用Adversarial Validation解决数据漂移问题

本文作者&#xff1a;杨健&#xff0c;九章云极 DataCanvas 主任架构师 数据漂移问题近年在机器学习领域来越来越得到关注&#xff0c;成为机器学习模型在实际投产中面对的一个主要挑战。当数据的分布随着时间推移逐渐发生变化&#xff0c;需要预测的数据和用于训练的数据分布…

格雷码的实现

格雷码&#xff1a;任意两个相邻的二进制数之间只有一位不同 想必通信专业的学生应该都接触过格雷码&#xff0c;它出现在数电、通信原理等课程里。 如下图所示一个四位格雷码是什么样子的&#xff1a; 格雷码的特点&#xff1a; 其最大的特点是任意上下相邻的两个码值间&am…

线性数据结构:数组 Array

一、前言数组是数据结构还是数据类型&#xff1f;数组只是个名称&#xff0c;它可以描述一组操作&#xff0c;也可以命名这组操作。数组的数据操作&#xff0c;是通过 idx->val 的方式来处理。它不是具体要求内存上要存储着连续的数据才叫数组&#xff0c;而是说&#xff0c…