Pytest--安装与入门

pytest是一个能够简化成测试系统构建、方便测试规模扩展的框架,它让测试变得更具表现力和可读性–模版代码不再是必需的。只需要几分钟的时间,就可以对你的应用开始一个简单的单元测试或者复杂的功能测试。

1. 安装pytest

pip install -U pytest

检查版本

> pytest --version
pytest 8.2.2

2. 创建第一个测试

注:

  • 文件名必须以 test 开头
  • 测试类必须以 Test 开头,且不能含有 init 方法
  • 测试方法必须以 test 开头
# test_sample.py
def func(x):
    return x + 1

def test_answer():
    assert func(3) == 5

然后在该python文件的目录下执行pytest

================================================= test session starts =================================================
platform win32 -- Python 3.9.9, pytest-7.0.1, pluggy-1.0.0
rootdir: D:\Code\Pytest
collected 1 item

test_sample.py F                                                                                                 [100%]

====================================================== FAILURES =======================================================
_____________________________________________________ test_answer _____________________________________________________

    def test_answer():
>       assert func(3) == 5
E       assert 4 == 5
E        +  where 4 = func(3)

test_sample.py:5: AssertionError
=============================================== short test summary info ===============================================
FAILED test_sample.py::test_answer - assert 4 == 5
================================================== 1 failed in 0.12s ==================================================
PS D:\Code\Pytest>

[100%]指的是运行所有测试用例的总体进度。完成后,pytest会显示一个报告,如上述测试,是一个失败报告,因为func(3)不返回5。

3. 运行多个测试

pytest _*.py或者pytest *_可以使 pytest 运行目录下的多个符合条件的文件。

3. pytest测试用例的运行方式

主函数模式

1. 运行所有:pytest.main()
import pytest

def fun_plus(x):
    return x+2

def test_answer():
    assert fun_plus(2) == 5

def test_addition():
    assert 1+1 == 2


if __name__ == '__main__':
    pytest.main()

执行结果

测试用例执行通过是没有的展示的,但执行失败会有具体的信息,甚至指出出错地方:

F:\SoftWare\Python\Python39\python39.exe F:/SoftWare/JetBrains/PyCharm2023.1.2/plugins/python/helpers/pycharm/_jb_pytest_runner.py --path F:\Code\PyCharmProject\Interview\pytest\test_demo01.py 
Testing started at 10:09 ...
Launching pytest with arguments F:\Code\PyCharmProject\Interview\pytest\test_demo01.py --no-header --no-summary -q in F:\Code\PyCharmProject\Interview\pytest

============================= test session starts =============================
collecting ... collected 2 items

test_demo01.py::test_answer FAILED                                       [ 50%]
test_demo01.py:5 (test_answer)
4 != 5

Expected :5
Actual   :4
<Click to see difference>

def test_answer():
>       assert fun_plus(2) == 5
E       assert 4 == 5
E        +  where 4 = fun_plus(2)

test_demo01.py:7: AssertionError

test_demo01.py::test_addition PASSED                                     [100%]

========================= 1 failed, 1 passed in 0.03s =========================

Process finished with exit code 1
2. 指定模块/文件
# test_demo01.py
import pytest

def fun_plus(x):
    return x+2

def test_answer():
    assert fun_plus(2) == 5

def test_addition():
    assert 1+1 == 2


# if __name__ == '__main__':
#     pytest.main()
# test_demo02.py
import pytest

def fun_minus(x):
    return x-2

def test_answer():
    assert fun_minus(2) == 5

def test_minus():
    assert 4-2 == 2


# if __name__ == '__main__':
#     pytest.main()
# run_suite.py
import pytest

if __name__ == '__main__':
    pytest.main(['-vs', './test_demo01.py', './test_demo02.py'])

参数详解:

-s:表⽰输出调试信息,输出print信息
-v:显⽰更加详细的信息
-vs:两个参数可以同时使⽤

注:main函数中的参数要求是列表形式的,如果有多个模块/文件,则继续以逗号分隔

多线程或者分布式运行:

安装插件 pytest-xdist

pip install pytest-xdist
# run_suite.py
import pytest

if __name__ == '__main__':
    pytest.main(['-vs', './', '-n 2'])
# 以两个线程来运行当前目录下的所有测试用例

执行结果:

============================= test session starts =============================
platform win32 -- Python 3.9.9, pytest-8.2.2, pluggy-1.5.0 -- F:\SoftWare\Python\Python39\python39.exe
cachedir: .pytest_cache
rootdir: F:\Code\PyCharmProject\Interview\pytest
plugins: xdist-3.6.1
created: 2/2 workers
2 workers [4 items]

scheduling tests via LoadScheduling

test_demo02.py::test_answer 
test_demo01.py::test_answer 
[gw0] FAILED test_demo01.py::test_answer 
[gw1] FAILED test_demo02.py::test_answer 
test_demo02.py::test_minus 
[gw1] PASSED test_demo02.py::test_minus 
test_demo01.py::test_addition 
[gw0] PASSED test_demo01.py::test_addition 

================================== FAILURES ===================================
_________________________________ test_answer _________________________________
[gw0] win32 -- Python 3.9.9 F:\SoftWare\Python\Python39\python39.exe

    def test_answer():
>       assert fun_plus(2) == 5
E       assert 4 == 5
E        +  where 4 = fun_plus(2)

test_demo01.py:7: AssertionError
_________________________________ test_answer _________________________________
[gw1] win32 -- Python 3.9.9 F:\SoftWare\Python\Python39\python39.exe

    def test_answer():
>       assert fun_minus(2) == 5
E       assert 0 == 5
E        +  where 0 = fun_minus(2)

test_demo02.py:7: AssertionError
=========================== short test summary info ===========================
FAILED test_demo01.py::test_answer - assert 4 == 5
FAILED test_demo02.py::test_answer - assert 0 == 5
========================= 2 failed, 2 passed in 0.34s =========================

Process finished with exit code 0
reruns 失败用例重跑

安装插件 pytest-rerunfailures

pip install pytest-rerunfailures

–reruns=num:失败用例重跑,将这个模块多执行num次,最后返回结果

# run_suite.py
import pytest

if __name__ == '__main__':
    pytest.main(['-vs', '--reruns=2'])

执行结果:

============================= test session starts =============================
platform win32 -- Python 3.9.9, pytest-8.2.2, pluggy-1.5.0 -- F:\SoftWare\Python\Python39\python39.exe
cachedir: .pytest_cache
rootdir: F:\Code\PyCharmProject\Interview\pytest
plugins: rerunfailures-14.0, xdist-3.6.1
collecting ... collected 4 items

test_demo01.py::test_answer RERUN
test_demo01.py::test_answer RERUN
test_demo01.py::test_answer FAILED
test_demo01.py::test_addition PASSED
test_demo02.py::test_answer RERUN
test_demo02.py::test_answer RERUN
test_demo02.py::test_answer FAILED
test_demo02.py::test_minus PASSED

================================== FAILURES ===================================
_________________________________ test_answer _________________________________

    def test_answer():
>       assert fun_plus(2) == 5
E       assert 4 == 5
E        +  where 4 = fun_plus(2)

test_demo01.py:7: AssertionError
_________________________________ test_answer _________________________________

    def test_answer():
>       assert fun_minus(2) == 5
E       assert 0 == 5
E        +  where 0 = fun_minus(2)

test_demo02.py:7: AssertionError
=========================== short test summary info ===========================
FAILED test_demo01.py::test_answer - assert 4 == 5
FAILED test_demo02.py::test_answer - assert 0 == 5
==================== 2 failed, 2 passed, 4 rerun in 0.05s =====================

Process finished with exit code 0
用例失败,测试停止

-x:只要有一个用例失败,测试就会停止

# run_suite.py
import pytest

if __name__ == '__main__':
    pytest.main(['-vs', '-x'])

执行结果:

============================= test session starts =============================
platform win32 -- Python 3.9.9, pytest-8.2.2, pluggy-1.5.0 -- F:\SoftWare\Python\Python39\python39.exe
cachedir: .pytest_cache
rootdir: F:\Code\PyCharmProject\Interview\pytest
plugins: rerunfailures-14.0, xdist-3.6.1
collecting ... collected 4 items

test_demo01.py::test_answer FAILED

================================== FAILURES ===================================
_________________________________ test_answer _________________________________

    def test_answer():
>       assert fun_plus(2) == 5
E       assert 4 == 5
E        +  where 4 = fun_plus(2)

test_demo01.py:7: AssertionError
=========================== short test summary info ===========================
FAILED test_demo01.py::test_answer - assert 4 == 5
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!
============================== 1 failed in 0.04s ==============================

Process finished with exit code 0
最大失败测试用例

–maxfail=n:如果有n个用例失败,测试就会停止(前提:安装插件 pytest-xdist)

# run_suite.py
import pytest

if __name__ == '__main__':
    pytest.main(['-vs', '--maxfail=1'])

执行结果:

============================= test session starts =============================
platform win32 -- Python 3.9.9, pytest-8.2.2, pluggy-1.5.0 -- F:\SoftWare\Python\Python39\python39.exe
cachedir: .pytest_cache
rootdir: F:\Code\PyCharmProject\Interview\pytest
plugins: rerunfailures-14.0, xdist-3.6.1
collecting ... collected 4 items

test_demo01.py::test_answer FAILED

================================== FAILURES ===================================
_________________________________ test_answer _________________________________

    def test_answer():
>       assert fun_plus(2) == 5
E       assert 4 == 5
E        +  where 4 = fun_plus(2)

test_demo01.py:7: AssertionError
=========================== short test summary info ===========================
FAILED test_demo01.py::test_answer - assert 4 == 5
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!
============================== 1 failed in 0.04s ==============================

Process finished with exit code 0
通过读取 pytest.ini 配置文件运行
# pytest.ini

[pytest]
# 命令行参数,用空格分隔
addopts = -vs

# 测试用例文件夹
testpaths = testcase
# run_suite.py
import pytest

if __name__ == '__main__':
    pytest.main(['--maxfail=1'])

已经将测试用例转移到 testcase 文件夹下,看看执行结果:

============================= test session starts =============================
platform win32 -- Python 3.9.9, pytest-8.2.2, pluggy-1.5.0 -- F:\SoftWare\Python\Python39\python39.exe
cachedir: .pytest_cache
rootdir: F:\Code\PyCharmProject\Interview\pytest
configfile: pytest.ini
testpaths: testcase
plugins: rerunfailures-14.0, xdist-3.6.1
collecting ... collected 4 items

testcase/test_demo01.py::test_answer FAILED

================================== FAILURES ===================================
_________________________________ test_answer _________________________________

    def test_answer():
>       assert fun_plus(2) == 5
E       assert 4 == 5
E        +  where 4 = fun_plus(2)

testcase\test_demo01.py:7: AssertionError
=========================== short test summary info ===========================
FAILED testcase/test_demo01.py::test_answer - assert 4 == 5
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!
============================== 1 failed in 0.04s ==============================

Process finished with exit code 0

更多的配置还有:


# 配置测试搜索的模块文件名称
python_files = test_*.py

# 配置测试搜索的测试类名
python_classes = Test*

# 配置测试搜索的函数名
python_functions = test*

4. pytest执行测试用例顺序

unittest默认的执行顺序:

按照ASCII大小执行的,即在写测试用例时将测试名按大小顺序或加上数字顺序大小即可使其按顺序执行。

pytest默认的执行顺序:

按照用例的先后顺序执行,即哪个用例写在前面就先执行哪个用例

当然我们也可以通过插件的方式自定义其执行顺序

安装 pytest-ordering 插件

pip install pytest-ordering

使用方法

@pytest.mark.run(order=1)

import pytest

def fun_plus(x):
    return x+2

def test_01_answer():
    assert fun_plus(2) == 5

@pytest.mark.run(order=1)
def test_02_addition():
    assert 1+1 == 2


if __name__ == '__main__':
    pytest.main()

5. 以安静报告模式执行测试用例

pytest -q test_sysexit.py

注:-q与--quiet的效果一样。

6. 分组执行测试用例

一旦开发了多个测试,你可能需要对测试进行分组,我们可以利用配置文件中的配置为测试进行分组执行:

@pytest.mark.组名

# pytest.ini
[pytest]
# 命令行参数,用空格分隔
addopts = -vs

# 测试用例文件夹
testpaths = ./testcase

# 分组
markers =
    smoke:冒烟用例
    group1:第一组测试用例
# test_demo02.py
import pytest

def fun_minus(x):
    return x-2


def test_answer():
    assert fun_minus(2) == 5

@pytest.mark.smoke
def test_minus():
    assert 4-2 == 2


if __name__ == '__main__':
    pytest.main(['./test_demo02.py', '-m', 'smoke'])

测试结果:

============================= test session starts =============================
platform win32 -- Python 3.9.9, pytest-8.2.2, pluggy-1.5.0 -- F:\SoftWare\Python\Python39\python39.exe
cachedir: .pytest_cache
rootdir: F:\Code\PyCharmProject\Interview\pytest
configfile: pytest.ini
plugins: ordering-0.6, rerunfailures-14.0, xdist-3.6.1
collecting ... collected 2 items / 1 deselected / 1 selected

test_demo02.py::test_minus PASSED

======================= 1 passed, 1 deselected in 0.02s =======================

Process finished with exit code 0

记一个PyCharm中可能遇到的问题

在单个test_xxx.py文件中,在main中传入了参数,但不管怎么运行都没有生效,在cmd窗口又是正常生效的,甚至在run_suite.py中的main也是正常的。这是因为程序自动识别到了pytest框架,默认以pytest运行,要main主函数运行。

解决方法:

1、修改Python解释器(但需要对每个test文件都这样,很麻烦)

Edit Configurations,新增解释器,将目标文件作为单独的python文件运行

2、修改Python integrated Tools(可以一劳永逸)

进入到File->Settings->Tools->Python integrated Tools页面,找到 Testing - Default test runner,将其修改为Unittest

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

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

相关文章

计算机人说学校-北京交通大学-计算机方向

北京交通大学&#xff08;Beijing Jiaotong University&#xff0c;简称BJTU&#xff09;是一所位于中国首都北京的全国重点大学&#xff0c;隶属于中华人民共和国教育部&#xff0c;并由教育部、交通运输部、北京市人民政府和中国国家铁路集团有限公司共建。该校是国家“双一流…

为什么 [] == ![] 为 true?

&#x1f9d1;‍&#x1f4bb; 写在开头 点赞 收藏 学会&#x1f923;&#x1f923;&#x1f923; 前言 面试官问我&#xff0c;[] ![] 的结果是啥&#xff0c;我&#xff1a;蒙一个true&#xff1b; 面试官&#xff1a;你是对的&#xff1b;我&#xff1a;内心非常高兴&a…

【PyTest】玩转HTML报告:修改、汉化和优化

前言 Pytest框架可以使用两种测试报告&#xff0c;其中一种就是使用pytest-html插件生成的测试报告&#xff0c;但是报告中有一些信息没有什么用途或者显示的不太好看&#xff0c;还有一些我们想要在报告中展示的信息却没有&#xff0c;最近又有人问我pytest-html生成的报告&a…

搜索型数据库的技术发展历程与趋势前瞻

概述 随着数字科技的飞速发展和信息量的爆炸性增长&#xff0c;搜索引擎已成为我们获取信息的首选途径之一&#xff0c;典型的代表厂商如 Google。然而&#xff0c;随着用户需求的不断演变&#xff0c;传统的搜索技术已经无法满足人们对信息的实时性、个性化和多样性的需求。 …

【启明智显技术分享】SSD202D核心板方案双网口SBC2D06开发板开箱与实操全攻略上手指南

一、背景 本指南将详细介绍启明智显基于SSD202D核心板方案下的双网口-SBC2D06的开箱及实操上手应用。无论您是电子爱好者、开发者还是工程师&#xff0c;这份指南都能助您快速上手并充分利用这款双网口开发板的各项功能。 二、硬件介绍 SBC2D06双网口开发板&#xff0c;作为…

什么方法能快速分享视频给他人?视频二维码提供预览的制作技巧

现在想要分享一个或者多个视频时&#xff0c;很多人会选择将视频生成二维码的方法来展现视频内容&#xff0c;通过这种方式可以让多人同时扫码查看同一个视频&#xff0c;有效提升其他人获取内容的速度及视频传播的效率。那么视频转换成二维码的方法是什么样的呢&#xff1f; …

USB PD+TYPE -C快充电源中MOSFET选型,USB PD应用市场包含智能手机,平板电脑,笔记本电脑,游戏本,移动硬盘,数码相机,电动工具等传统领域

USB PD全称为USB Power Delivery&#xff0c;是由USB-IF组织制定的一种快速充电协议&#xff0c;也是目前市场非常看好的一种协议&#xff0c;可以支持输出功率高达100W&#xff1b;Type-C是一种接口规范&#xff0c;能够支持传输更大的电流。USB PD应用市场不仅包含智能手机&a…

【项目】个人论坛测试报告

论坛测试报告 一、项目背景二、项目功能三、测试计划一&#xff09;功能测试二&#xff09;自动化测试三&#xff09;性能测试登录测试 使用VUG创建脚本1&#xff09;编写用户进行登录的脚本2&#xff09;对脚本进行强化 使用controller创建场景使用Analysis生成测试报告测试报…

NX 二次开发-获取CAM切削层数据

int count 0;tag_t* objects;UF_UI_ONT_ask_selected_nodes(&count, &objects); //获取当前加工导航器选中的对象数量和tagif (count < 0){return 0;}UF_CUT_LEVELS_t* cut_levels_ptr_addr NULL; //读工序的切削层UF_CUT_LEVELS_load(objects[0], &…

高考失利咨询复读,银河补习班客服开挂回复

补习班的客服在高考成绩出来后&#xff0c;需要用专业的知识和足够的耐心来回复各种咨询&#xff0c;聊天宝快捷回复软件&#xff0c;帮助客服开挂回复。 ​ 前言 高考成绩出来&#xff0c;几家欢喜几家愁&#xff0c;对于高考失利的学生和家长&#xff0c;找一个靠谱的复读补…

Python的库dataperp读取excel和csv

领导说这个很牛&#xff0c;不过咱们不能听别人一口之言&#xff0c;咱们应该亲手试试&#xff0c;在来说这个好或者不好。 这个dataprepe已经不维护了&#xff0c;最高只支持python3.11以下版本,建议选择3.9. 他只能处理dataframe格式的数据&#xff0c;也就是pandas加载后的数…

monkey大全!可直接运用在项目中的常规monkey命令

测试步骤 adb devices-----了解包名-----adb shell monkey -----p 包名 ----v 运行次数&#xff08;多个参数的组合形成不同的用例以求最大的覆盖&#xff09;-----当崩溃或无响应时分析monkey日志 常规monkey命令 &#xff08;可直接在项目里使用&#xff09; adb shell m…

CAD图纸怎么加密?(五种简单的CAD图纸加密方法分享)

在企业中&#xff0c;CAD图纸通常含有许多敏感且机密信息&#xff0c;对设计图纸的安全保护至关重要。为确保CAD图纸不被未经授权的人访问、复制或篡改&#xff0c;企业需要采用有效的加密措施。以下是一些常用的方法和工具&#xff0c;帮助企业对CAD图纸进行加密保护&#xff…

飞睿uwb防丢定位器芯片方案,厘米级无线定位测距,超宽带可传输可MESH组网模块

在信息爆炸的时代&#xff0c;我们的生活越来越离不开各种各样的智能设备。从手机到手表&#xff0c;从智能家居到无人驾驶&#xff0c;科技的进步让我们的生活变得更加便捷、高效。然而&#xff0c;随着我们拥有的物品越来越多&#xff0c;如何确保这些物品的安全&#xff0c;…

Rabbitmq部署

环境 操作系统CentOS7 安装 准备安装包 # rabbitmq基于erlang语言开发&#xff0c;需先安装erlang语言解释器 [rootnode2 ~]# ls erlang-21.3-1.el7.x86_64.rpm rabbitmq-server-3.8.8-1.el7.noarch.rpm [rootnode2 ~]# rpm -ivh erlang-21.3-1.el7.x86_64.rpm #安装soca…

玉林师范学院宿舍管理系统的设计与实现19633

玉林师范学院宿舍管理系统设计与实现 摘要&#xff1a;随着大学生人数的增加&#xff0c;宿舍管理成为高校管理中的重要问题。本论文旨在研究玉林师范学院宿舍管理系统&#xff0c;探讨其优势和不足&#xff0c;并提出改进建议。通过对相关文献的综述和实地调研&#xff0c;我们…

MobileNetsV1、MobileNetsV2、MobileNetsV3

参考来源&#xff1a; MobileNet(V1,V2,V3)网络结构详解与模型的搭建_bneck结构图-CSDN博客轻量级神经网络MobileNet全家桶详解-CSDN博客 汇总 MobileNetsV1特性&#xff1a; MobileNetsV2特性 &#xff1a; MobileNetsV3特性 &#xff1a; 三者特性汇总&#xff1a; Mobil…

button1 <Button>: Missing Constraints in ConstraintLayout

书籍 《第一行代码 Android》第三版 开发 环境 Android Studio Jellyfish | 2023.3.1 问题 在学习3.2.2 创建和加载布局章节,在first_layout.xml中增加一个按钮button1时报错:"button1 <Button>: Missing Constraints in ConstraintLayout" 分析 产生这个…

香橙派OrangePi AIpro初体验:当小白拿到一块开发板第一时间会做什么?

文章目录 香橙派OrangePi AIpro初体验&#xff1a;当小白拿到一块高性能AI开发板第一时间会做什么前言一、香橙派OrangePi AIpro概述1.简介2.引脚图开箱图片 二、使用体验1.基础操作2.软件工具分析 三、香橙派OrangePi AIpro.测试Demo1.测试Demo1&#xff1a;录音和播音(USB接口…