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

python中pytest库用法详解

Pytest 是用于测试 Python 应用的 Python 库。

官方文档:Full pytest documentation — pytest documentation

安装:

pip install pytest

pytest 测试发现约定规范

        如果未指定任何参数,则在testpaths(如果已配置)或当前目录中的位置搜索测试文件。 另外,命令行参数可以在目录,文件名或节点 ID 的任何组合中使用。

        pytest 在所选目录中查找test_*.py或*_test.py文件。所有的单测文件名都需要满足test_*.py格式或*_test.py格式。

        在选定的文件中,pytest 在类之外查找带前缀的测试函数,并在带前缀的测试类中查找带前缀的测试方法(无__init__()方法)。

        在单测文件中,测试类以Test开头,并且不能带有 __init__ 方法。注意:定义class时,需要以大写T开头。

        在单测类中,可以包含一个或多个test_开头的函数。

        注意:测试函数名必须要以test开头。

命令中参数:

指令含义指令
用于详细显示日志信息-v
测试结果的简单统计-rA
只显示整体测试结果-q
帮助-h
显示print打印信息-s
输出html格式报告–html=path输出路径
生成log报告–resultlog=./log.txt (6.1 版本之后被删除)
生成xml报告–junitxml=./log.xml
当错误达到num时,停止测试–maxfail=num
只运行有MARKEXPR(自定义)标记的测试-m MARKEXPR
生成简略的指定需求的报告-r option

运行 pytest

 max_min_func.py

def max_value(values):
    _max = values[0]

    for val in values:
        if val > _max:
            _max = val
    return _max


def min_value(values):
    _min = values[0]

    for val in values:
        if val < _min:
            _min = val
    return _min

max_min_test.py

import max_min_func


def test_min():
    values = [3, 5, 8, 1, 9, 2]
    val = max_min_func.min_value(values)
    assert val == 1


def test_max():
    values = [3, 5, 8, 1, 9, 2]
    val = max_min_func.max_value(values)
    assert val == 9


test_min()

        pytest 不带任何参数,将查看当前工作目录(或其他一些预配置的目录)以及测试文件的所有子目录,并运行找到的测试代码。

运行当前目录中的所有测试文件。

pytest

通过指定名称作为参数来运行特定的测试文件。 

pytest max_min_test.py

通过在::字符后提供其名称来运行特定功能。

pytest max_min_test.py::test_max

将上述max_min_test.py中test_max()函数的asset val == 9 改为val == 8,再执行测试代码:

Pytest 跳过

        使用跳过装饰器,可以跳过指定的测试。 跳过测试有多种原因。 例如,数据库/在线服务目前不可用,或者跳过了 Windows 上针对 Linux 的特定测试。

将上面max_min_test.py代码改写如下:

import max_min_func
import pytest


@pytest.mark.skip
def test_min():
    values = [3, 5, 8, 1, 9, 2]
    val = max_min_func.min_value(values)
    assert val == 1


def test_max():
    values = [3, 5, 8, 1, 9, 2]
    val = max_min_func.max_value(values)
    assert val == 9


test_min()

pytest 标记

        使用标记将测试组织为单元。标记可用于对测试进行分组。 然后使用pytest -m运行一组标记的测试。

marking.py

import pytest


@pytest.mark.a
def test_a1():
    assert (1) == (1)


@pytest.mark.a
def test_a2():
    assert (1, 2) == (2, 1)


@pytest.mark.a
def test_a3():
    assert (1, 2, 3) == (1, 2, 3)


@pytest.mark.b
def test_b1():
    assert "falcon" == "fal" + "con"


@pytest.mark.b
def test_b2():
    assert "falcon" == f"fal{'con'}"

Pytest 参数化测试

        通过参数化测试,可以向断言中添加多个值。 使用@pytest.mark.parametrize标记。

param_test.py

import max_min_func
import pytest


@pytest.mark.parametrize("data, expected", [((2, 3, 1, 4, 6), 1),
                                            ((5, -2, 0, 9, 12), -2), ((200, 100, 0, 300, 400), 0)])
def test_min(data, expected):
    val = max_min_func.min_value(data)
    assert val == expected


@pytest.mark.parametrize("data, expected", [((2, 3, 1, 4, 6), 6),
                                            ((5, -2, 0, 9, 12), 12), ((200, 100, 0, 300, 400), 400)])
def test_max(data, expected):
    val = max_min_func.max_value(data)
    assert val == expected

pytest 夹具

        测试需要在一组已知对象的背景下进行。 这组对象称为测试夹具。

func_test.py

def max_value(values):
    _max = values[0]

    for val in values:
        if val > _max:
            _max = val
    return _max


def min_value(values):
    _min = values[0]

    for val in values:
        if val < _min:
            _min = val
    return _min


def list_sort(data):
    if not isinstance(data, list):
        vals = list(data)
    else:
        vals = data

    size = len(vals)
    for i in range(0, size):
        for j in range(i + 1, size):
            if vals[j] < vals[i]:
                _min = vals[j]
                vals[j] = vals[i]
                vals[i] = _min
    return vals


if __name__ == '__main__':
    aa = list_sort([5, 6, 1, 8])
    print(aa)

fix_test.py

import func_test
import pytest


@pytest.fixture
def data():
    return [4, 6, 5, 7, 2, 3, 9, 11, -3]


def test_sort(data):
    sort_val = func_test.list_sort(data)
    assert sort_val == sorted(data)

Pytest 布局

        Python 测试可以多种方式组织。 测试可以集成在 Python 包中,也可以放在包外。

外部测试

内部测试

函数数据参数化

方便测试函数对参数的调用:

@pytest.mark.parametrize(argnames,argvalues, indirect=False, ids=None, scope=None)
argnames:参数名
argvalues:参数对应值,可传多个值,类型必须为list [(values1,values2,…),(value1,value2,…)]

pytest 会将定义好的参数列表逐个填入到参数位置中执行代码,有多少个执行多少遍

import pytest

'''
parametrize
'''


class TestFunc(object):
    def setup_class(self):
        print("---------setup_class----------")

    def teardown_class(self):
        print("------------teardown_class-------------")

    # 传递单参数
    @pytest.mark.parametrize("a", [3, 6])
    def test_1(self, a):
        print("a = %d" % a)
        assert a % 3 == 0

    # 传递多参数
    @pytest.mark.parametrize('a,b', [(0, 3), [1, 2]])
    def test_2(self, a, b):
        print("%d + %d = %d" % (a, b, a + b))
        assert a + b == 3


if __name__ == "__main__":
    pytest.main(['-s', '-v', 'parametrize_test.py::TestFunc::test_1'])
    pytest.main(['-s', '-v', 'parametrize_test.py::TestFunc::test_2'])

多进程运行CASE

        当cases量很多时,运行时间也会变的很长,如果想缩短脚本运行的时长,就可以用多进程来运行。

安装pytest-xdist:

pip install -U pytest-xdist

运行方法:

pytest test_se.py -n NUM

其中NUM填写并发的进程数。

生成HTML报告

安装pytest-html:

pip install pytest-html

使用时直接在命令行pytest命令后面加--html=<文件名字或者路径>.html参数就可以了。

pytest max_min_test.py --html=report.html

        上面生成的报告包括html和一个assets文件(里面是报告CSS样式),如果要合成一个文件可以添加下面的参数。

pytest max_min_test.py --html=report.html --self-contained-html

生成XML报告

pytest --junitxml=report.xml

参考博文:

Python Pytest 教程|极客教程

Python 测试框架 pytest —— 使用教程 - 又见苍岚

pytest使用总结笔记 - fengf233 - 博客园

相关文章:

  • CSRF漏洞简介
  • C/C++航空客运订票系统
  • 编译原理之词法分析器随笔和简单实现
  • 47 - 父子间的冲突
  • 单片机和ARM A的区别
  • STC 51单片机40——汇编语言 串口 接收与发送
  • python破解wifi教程
  • Android App开发即时通信中通过SocketIO在客户端与服务端间传输文本和图片的讲解及实战(超详细 附源码)
  • 【网络安全】文件上传之安全狗bypass
  • MATLAB | 世界杯来用MATLAB画个足球玩叭~
  • LeetCode | 循环队列的爱情【恋爱法则——环游世界】
  • Android App开发音量调节中实现拖动条和滑动条和音频管理器AudioManager讲解及实战(超详细 附源码和演示视频)
  • 电视剧里的代码真能运行吗?
  • 让我们进入面向对象的世界(三)
  • 动态域名解析
  • 5、React组件事件详解
  • angular学习第一篇-----环境搭建
  • avalon2.2的VM生成过程
  • classpath对获取配置文件的影响
  • create-react-app项目添加less配置
  • javascript从右向左截取指定位数字符的3种方法
  • JS字符串转数字方法总结
  • Mac转Windows的拯救指南
  • PHP的Ev教程三(Periodic watcher)
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • 工作中总结前端开发流程--vue项目
  • 入手阿里云新服务器的部署NODE
  • 世界上最简单的无等待算法(getAndIncrement)
  • 数据仓库的几种建模方法
  • 线上 python http server profile 实践
  • 写代码的正确姿势
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • 怎么把视频里的音乐提取出来
  • puppet连载22:define用法
  • 我们雇佣了一只大猴子...
  • ​水经微图Web1.5.0版即将上线
  • (3)STL算法之搜索
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (Note)C++中的继承方式
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • **PHP分步表单提交思路(分页表单提交)
  • ... 是什么 ?... 有什么用处?
  • .java 9 找不到符号_java找不到符号
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .Net Core 中间件验签
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • [1204 寻找子串位置] 解题报告
  • [Android]How to use FFmpeg to decode Android f...
  • [BZOJ3757] 苹果树
  • [CareerCup][Google Interview] 实现一个具有get_min的Queue
  • [CSS] - 修正IE6不支持position:fixed的bug
  • [Docker]六.Docker自动部署nodejs以及golang项目
  • [EFI]Lenovo ThinkPad X280电脑 Hackintosh 黑苹果引导文件