python 自动化测试 pytest 的使用

news2025/7/20 6:56:49

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():
    pass

import time

DATE_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))))

    yield

    finished = 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:02

SETUP    S timer_session_scope
    SETUP    M module_scope
      SETUP    C class_scope
        SETUP    F function_scope
        test_pytest_study.py::test_3 (fixtures used: class_scope, function_scope, module_scope, timer_session_scope).
        TEARDOWN F function_scope
      TEARDOWN C class_scope
      SETUP    C class_scope
        SETUP    F function_scope
        test_pytest_study.py::test_4 (fixtures used: class_scope, function_scope, module_scope, timer_session_scope).
        TEARDOWN F function_scope
      TEARDOWN C class_scope
    TEARDOWN M module_scope
session finished: 2020-04-16 17:29:05
session Total time cost: 3.087s

TEARDOWN 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 pytest

class 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 fixture

        SETUP    F postcode
        test_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)
    yield
    print("\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 passwd1

test_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.coloradmin.cn/o/368778.html

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

相关文章

论文投稿指南——中文核心期刊推荐(综合性经济科学 2)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

JavaScript 测试 Prototype

文章目录JavaScript 测试 Prototype引用 PrototypePrototype 描述测试 PrototypeJavaScript 测试 Prototype 测试 JavaScript 框架库 - Prototype 引用 Prototype 如需测试 JavaScript 库&#xff0c;您需要在网页中引用它。 为了引用某个库&#xff0c;请使用 <!DOCTYP…

【Opencv项目实战】目标追踪:实时追踪人工标注的多个目标

文章目录一、项目思路二、问题清单三、算法详解3.1、定义目标追踪算法3.2、初始化追踪器3.3、更新目标追踪器3.4、绘制目标矩形框3.5、人工标注感兴趣目标3.5.1、标注ROI区域3.5.2、截取ROI区域四、项目实战&#xff1a;单目标 - 实时追踪五、项目实战&#xff1a;多目标 - 实时…

一文教会你如何在Linux系统中使用Docker安装Redis 、以及如何使用可视化工具连接【详细过程+图解】

文章目录1、安装redis2、在外部创建配置文件3、创建redis4、启动测试redis5、数据持久化存储6、使用可视化工具连接redis前言在windows上安装过reids、在linux上也安装过redis&#xff0c;但是都没有docker上安装redis方便。这里给出docer安装redis的相关教程1、安装redis 默认…

Python|Pymol的安装

​Pymol的使用其实可以分为两种&#xff0c;一种是GUI图形操作界面&#xff0c;直接可以去Pymol官网上下&#xff0c;另一种则是使用API的方式直接调用&#xff0c;适合写脚本批量处理一些东西。建议画图&#xff0c;看结构直接用GUI&#xff0c;但是计算RMSD啥的&#xff0c;用…

【OJ】盐荒子孙

&#x1f4da;Description: 盐体图 盐是对人类生存具有重要意义的物质之一。当中国古人从肉食为主转向谷食为主的时候&#xff0c;吃盐的需求就发生了&#xff0c;因为动物血肉里面包含有足够人体所需的盐分&#xff0c;而谷 物本身不包含盐分。在长达几十万年的旧石器时代&…

localStorage和sessionStorage

目录 一、localStorage和SessionStorage在哪里&#xff0c;是什么 二、localStorage和sessionStorage区别 三、localStorage常用方法 四、sessionStorage常用方法 一、localStorage和SessionStorage在哪里&#xff0c;是什么 【1】在浏览器开发者工具的Application栏目里&…

2023年消费电子行业研究报告

第一章 行业概况 消费电子行业是电子信息行业的子行业。消费电子是指围绕着消费者应用而设计的与生活、工作和娱乐息息相关的电子类产品&#xff0c;通常会应用于娱乐、通讯以及文书用途&#xff0c;最终实现消费者自由选择资讯、享受娱乐的目的&#xff0c;主要侧重于个人购买…

Gephi快速入门

Gephi快速入门1. 导入文件&#xff08;Import file&#xff09;2. 布局&#xff08;Layout&#xff09;3. 排序&#xff08;Ranking&#xff09;4. 指标&#xff08;Metrics&#xff09;5. 标签&#xff08;Label&#xff09;6. 社区发现&#xff08;Community detection&#…

AI入场,搜索这个“营销枢纽”有新故事吗?

哪里有内容&#xff0c;哪里就有搜索。 以前&#xff0c;互联网离我们生活很远&#xff0c;传统搜索与用户的距离分割&#xff0c;只有当用户想要了解什么&#xff0c;才会去使用。 如今&#xff0c;互联网与真实世界密不可分&#xff0c;加之新技术、新平台的不断涌现&#xf…

Python年利率计算器【N日年化收益率】

现在有闲钱的人&#xff0c;按照聪明等级从低到高排序应该是钱买股票&#xff0c;一年利率约为-20%钱放银行活期&#xff0c;年利率约为0.3%钱放银行定期&#xff0c;一年利率约为1.5%钱放余额宝&#xff08;支付宝&#xff09;或零钱通&#xff08;微信&#xff09;&#xff0…

ChatGPT和Web3:人工智能如何帮助您建立和发展您的 Web3 公司

ChatGPT是OpenAI在2022年11月推出的聊天机器人。该机器人建立在OpenAI的GPT-3人工智能家族上&#xff0c;并通过监督学习和强化学习技术进行了优化。 与ChatGPT机器人聊天时&#xff0c;你会感觉自己在与一个懂得一切并以非常教育性的方式回答的朋友交谈。回答在许多知识领域非…

文件上传+easyExcel

文章目录需求描述实现0、依赖1、编写配置类2、文件上传工具类3、编写Controller4、编写Service5、编写excel对应的类6、创建easyExcel的监听器7、最终效果需求描述 页面中当用户将excel表格上传到服务器后&#xff0c;将该excel文件保存在本地然后在服务器中将excel中的数据读取…

预编译(回顾)

浏览器运行机制变量提升机制私有变量提升步骤全局对象 GO 和全局变量对象 VO的区别带var和不带var的区别系统输出顺序变量提升在条件判断下的处理防止函数的变量提升 浏览器运行机制 为了能够让代码执行&#xff0c;浏览器首先会形成一个执行环境栈 ECStack(Execution Contex…

15- 答题卡识别及分数判定项目 (OpenCV系列) (项目十五)

项目要点 图片读取 : img cv2.imread(./images/test_01.png)灰度图: gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)高斯模糊: blurred cv2.GaussianBlur(gray, (5, 5), 0) # 去噪点边缘检测: edged cv2.Canny(blurred, 75, 200)检测轮廓: cnts cv2.findContours(e…

Ai作画studio环境布置

大家好&#xff0c;今天跟大家介绍如何用stable diffusion webui布置自己的Ai作画工作环境。这部分主要就是实操&#xff0c;没有太多理论知识介绍。跟着做就好了&#xff0c;当成是一次计算机实验上机课就好基础环境布置这次开发环境选择的是AutoDL的GPU云环境&#xff0c;链接…

ros下用kinectv2运行orbslam2

目录 前提 创建工作空间 orbslam2源码配置、测试&#xff1a; 配置usb_cam ROS功能包 配置kinect 前提 vim 、 cmake 、 git 、 gcc 、 g 这些一般都装了 主要是Pangolin 、 OpenCV 、 Eigen的安装 18.04建议Pangolin0.5 创建工作空间 我们在主目录下创建一个catkin_…

听车企做开发朋友说,面试Framework 必问~

近期听在车企工作的朋友说&#xff0c;今年去他们公司面试的人比往年增长了30%左右&#xff0c;但实际面试达到标准的人屈指可数&#xff0c;大多都是从 Android 开发方向转过来的。 车企招聘要求有哪些&#xff1f; 每个车企因为业务部门的不同&#xff0c;他们的要求也会有…

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

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

搭建直播平台服务器什么配置最合适?直播平台专用服务器(驰网i9-13900k服务器)

如今&#xff0c;视频直播越来越受欢迎&#xff0c;视频和直播平台也越来越多&#xff0c;直播平台和视频网站都需要更好的服务器来支持。那么&#xff0c;视频直播平台需要什么服务器呢&#xff1f;以一个简单的直播网站为例。如果每天在线人数约1000人&#xff0c;同时在线人…