python单测框架之pytest常见用法

news2024/11/15 7:06:55

单测框架的作用

  • 测试发现:从多个文件中寻找测试用例。
  • 测试执行:按照一定顺序去执行并且生成结果。
  • 测试断言:判断最终结果与实际结果的差异。
  • 测试报告:统计测试进度、耗时、通过率,生成测试报告。

pytest简介

pytest是python的单测框架,使用灵活,插件丰富,以下是pytest常用的插件

  • pytest
  • pytest-html:生成html测试报告插件
  • pytest-xdist:多线程执行用例插件
  • pytest-ordering:自定义用例顺序插件
  • pytest-rerunfailures:失败重跑插件
  • allure-pytest:生成allure美观测试报告插件

pip install 就行,只有有这些插件,下面的某些命令行才生效

pytest默认规则

  • 模块名必须以test_开头或者_test结尾
  • 类名必须以Test开头
  • 测试方法必须以test开头
  • pytest用例运行顺序默认从上到下(代码中可以使用装饰器@pytest.mark.run(order=1)来指定执行顺序)

使用pytest.ini文件可以修改默认规则

pytest的运行方式

主函数模式

1

2

3

4

import pytest

if __name__ == '__main__':

    pytest.main(["-vs", "./test_demo/test_demo1.py"])

这样就可以运行所有用例

命令行模式

1

pytest -vs ./test_demo/test_demo1.py

参数详解
  1. -s:输出调试的信息
  2. -v:表示详细的方式输出
  3. ./test_demo/test_demo1.py表示运行指定模块,相对路径表示
  4. ./test_demo/test_demo1.py::TestCase1::test_case1 nodeid表示,代表运行./test_demo/test_demo1.py模块下的TestCase1类的test_case1 方法
  5. -n分布式运行测试用例,-n num,参数num代表几个线程运行用例
  6. –reruns=2表示用例失败重跑2次,常用于一些不稳定的用例,如web自动化
  7. -x只要有一个用例报错,那么就会停止
  8. –maxfail=2,有2个用例失败就会停止
  9. -k根据测试用例部分字符串指定测试用例,如 -k “ao”,代表会执行带有ao名称的字符串

读取pytest.ini配置文件运行

不论是主函数模式还是命令行模式都会读取这个配置文件,该文件需要使用gbk编码,下面是这个配置文件的例子

1

2

3

4

5

6

7

8

9

10

11

[pytest]

# 命令行参数,用空格分隔

addopts = -vs

# 测试用例文件夹,可以自己配置

testpaths = ./test_demo

# 配置测试搜索的模块文件名称

python_files = test*.py

# 配置测试搜索的类名

python_classes = Test*

# 配置搜索的函数名

python_functions = test

分组执行

定义三个组,冒烟:smoke,用户管理:user_manager,作业管理:worker_manager

目前有几个用例给加个分组的装饰器

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

import pytest

class TestDemo:

    @pytest.mark.somke

    def test_case1(self):

        print("1")

    @pytest.mark.user_manage

    def test_case2(self):

        print("2")

    @pytest.mark.worker_manage

    def test_case3(self):

        print("3")

配置文件中加入分组信息

1

2

3

4

markers =

    smoke:冒烟测试

    user_manage:用户管理

    worker_manage:作业管理

运行
运行多组

1

2

3

4

import pytest

if __name__ == '__main__':

    pytest.main(["-vs", "-m smoke or usermanage"])

运行单组

1

2

3

4

import pytest

if __name__ == '__main__':

    pytest.main(["-vs", "-m smoke"])

忽略执行

无条件忽略

直接使用装饰器@pytest.mark.skip(reason=“原因填写”)

有条件忽略

使用装饰器@pytest.mark.skipif(条件, 原因)

例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

import pytest

class TestDemo:

    age = 18

    @pytest.mark.smoke

    def test_case1(self):

        print("1")

    @pytest.mark.usermanage

    @pytest.mark.skipif(age < 18, "未成年")

    def test_case2(self):

        print("2")

    @pytest.mark.workermanage

    @pytest.mark.skip(reason="原因填写")

    def test_case3(self):

        print("3")

pytest中的前后置处理

为什么需要前后置?比如执行用例前需要做一些准备工作,比如打开浏览器,在执行用例后需要一些后置工作,比如关闭浏览器

模块级别

在每个模块执行前会调用setup_module方法,在每个模块执行后会使用teardown_module方法。
例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

import pytest

def setup_module():

    print("模块用例前执行")

def teardown_module():

    print("模块用例后执行")

class TestDemo:

    def test_case1(self):

        print("1")

    def test_case2(self):

        print("2")

    def test_case3(self):

        print("3")

class TestDemo2:

    def test_case4(self):

        print("4")

结果:

1

2

3

4

5

6

7

8

9

test_demo/test_demo2.py::TestDemo::test_case1 模块用例前执行

1

PASSED

test_demo/test_demo2.py::TestDemo::test_case2 2

PASSED

test_demo/test_demo2.py::TestDemo::test_case3 3

PASSED

test_demo/test_demo2.py::TestDemo2::test_case4 4

PASSED模块用例后执行

类级别

类级别函数 setup_class/teardown_class 对类有效,位于类中,在测试类中前后调用一次。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

class TestDemo:

    def setup_class(self):

        print("类级别前置")

    def test_case1(self):

        print("1")

    def test_case2(self):

        print("2")

    def test_case3(self):

        print("3")

    def teardown_class(self):

        print("类级别后置")

1

2

3

4

5

6

7

8

9

test_demo/test_demo2.py::TestDemo::test_case1 模块用例前执行

类级别前置

1

PASSED

test_demo/test_demo2.py::TestDemo::test_case2 2

PASSED

test_demo/test_demo2.py::TestDemo::test_case3 3

PASSED类级别后置

模块用例后执行

方法级别

方法级别函数 setup_method/teardown_method和setup/teardown对类有效,也位于类中,这两个效果一样,在测试类中每个测试方法前后调用一次。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

class TestDemo:

    def setup_method(self):

        print("方法级别前置")

    def test_case1(self):

        print("1")

    def test_case2(self):

        print("2")

    def test_case3(self):

        print("3")

    def teardown_method(self):

        print("方法级别后置")

1

2

3

4

5

6

7

8

9

10

11

test_demo/test_demo3.py::TestDemo::test_case1 方法级别前置

PASSED方法级别后置

test_demo/test_demo3.py::TestDemo::test_case2 方法级别前置

PASSED方法级别后置

test_demo/test_demo3.py::TestDemo::test_case3 方法级别前置

PASSED方法级别后置

部分用例的前后置 pytest.fixture装饰器

1

2

3

4

5

6

7

8

9

10

11

12

13

14

import pytest

@pytest.fixture(scope="function", params=["1", "2", "3"], autouse=False, ids=None, name="new_name")

def my_feature(request):

    i = request.param

    print("前置")

    yield i

    print("后置")

class TestDemo:

    def test_case1(self, new_name):

        print(new_name)

        print("1")

结果

test_demo/test_demo4.py::TestDemo::test_case1[1] 前置
1
1
PASSED后置

test_demo/test_demo4.py::TestDemo::test_case1[2] 前置
2
1
PASSED后置

test_demo/test_demo4.py::TestDemo::test_case1[3] 前置
3
1
PASSED后置

  • scope:表示作用域
  • params:表示参数化,与yield使用会调用len(params)次用例,如例子所示,一般用于数据驱动
  • autouse:默认使用,一般设置为false
  • ids:params参数化时,给每个参数起名字
  • name:给该方法取别名

pytest.fixture+conftest

fixture为session级别是可以跨.py模块调用的,也就是当我们有多个.py文件的用例的时候,如果多个用例只需调用一次fixture,那就可以设置为scope=“session”,并且写到conftest.py文件里。

conftest.py文件名称时固定的,pytest会自动识别该文件。放到项目的根目录下就可以全局调用了,如果放到某个package下,那就在改package内有效。

例子:
在包下创建conftest.py,注意,该配置只在本包生效

在这里插入图片描述

和之前一样使用

在这里插入图片描述

结果还是和之前一样。

pytest生成测试报告

pytest-html插件生成报告

1

pytest -vs --html ./report/report.html

参数化与数据驱动

主要用的装饰器是@pytest.mark.parametrize(argnames, argvalues)

不带名字数据驱动

1

2

3

4

5

6

import pytest

class TestDemo:

    @pytest.mark.parametrize("args",[(4399, 'AAAA'), (2012, 'BBBB')])

    def test_case1(self, args):

        print(args)

结果:

test_demo/test_demo4.py::TestDemo::test_case1[args0] (4399, ‘AAAA')
PASSED
test_demo/test_demo4.py::TestDemo::test_case1[args1] (2012, ‘BBBB')
PASSED 带名字的数据驱动

1

2

3

4

5

6

import pytest

class TestDemo:

    @pytest.mark.parametrize("arg1,arg2", [(4399, 'AAAA'), (2012, 'BBBB')])

    def test_case1(self, arg1, arg2):

        print(arg1, arg2)

结果:

test_demo/test_demo4.py::TestDemo::test_case1[4399-AAAA] 4399 AAAA
PASSED
test_demo/test_demo4.py::TestDemo::test_case1[2012-BBBB] 2012 BBBB
PASSED

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走! 希望能帮助到你!【100%无套路免费领取】

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

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

相关文章

51单片机10(蜂鸣器介绍)

一、蜂鸣器介绍&#xff1a; 1、蜂鸣器是一种一体化结构的电子讯响器&#xff0c;采用直流电压供电&#xff0c;广泛应用于电子产品中作为发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器。 &#xff08;1&#xff09;压电式蜂鸣器&#xff0c;它主要由多谐的一个增胀器…

Cyber Weekly #15

赛博新闻 1、OpenAI 绝密项目「草莓」首次曝光 据外媒路透社报道&#xff0c;OpenAI 内部正在一个代号为「草莓&#xff08;Strawberry&#xff09;」的项目中开发一种新的人工智能模型。该模型细节此前从未被报道过&#xff0c;而 OpenAI 正在努力证明该模型类型能够提供高级…

C++客户端Qt开发——信号和槽

三、信号和槽 1.信号和槽概述 在Qt中&#xff0c;用户和控件的每次交互过程称为一个事件。比如"用户点击按钮”是一个事件&#xff0c;"用户关闭窗口”也是一个事件。每个事件都会发出一个信号&#xff0c;例如用户点击按钮会发出"按钮被点击"的信号&…

ensp防火墙智能选举综合实验

实验要求&#xff1a; 实验图&#xff1a; 新增配置&#xff1a; 路由isp: 7&#xff1a; 保留ip操作&#xff1a; 一、DX区域&#xff1a; 1、源地址池配置&#xff1a; 2、nat策略&#xff1a; nat安全策略配置&#xff1a; 二、YD&#xff1a; 1、源地址池配置&#xf…

最值得推荐的10款Windows软件!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频播放量破百万https://aitools.jurilu.com/1.音乐播放器——Dopamine Dopamine是一款音乐播放器&#xff0c;设计简洁美观。它支持多种音频格式&#xff0c;包括wav、mp3、ogg…

平衡树——AcWing 253. 普通平衡树

平衡树 定义 平衡树是一种自平衡的二叉搜索树&#xff0c;它在进行插入和删除操作后能够自动调整其结构&#xff0c;以保持树的高度尽可能低&#xff0c;从而保证树的查找、插入和删除操作能够在对数时间内完成。最著名的平衡树有AVL树和红黑树。 AVL树&#xff1a;是一种严格…

10月23-25日|2024年武汉袋式除尘展重磅来袭

2024第六届&#xff08;武汉&#xff09;国际袋式除尘技术与设备展览会 时间&#xff1a;2024年10月23-25日 地点&#xff1a;武汉国际文化博览中心 展会介绍&#xff1a; 2024第6届&#xff08;武汉&#xff09;国际袋式除尘技术与设备展览会将于2024年10月23-25日在武汉文…

Linux进程理解

一、进程的理解 首先我们知道我们的操作其实都是在运行程序&#xff0c;不仅是在windows上打开软件还是在Linux上执行指令&#xff0c;而程序存在于磁盘上&#xff0c;程序的要想运行就要把程序的代码和数据从磁盘加载到内存&#xff0c;那么到这一步是创建了一个进程吗&#…

c#中的特性

在C#中&#xff0c;特性&#xff08;Attributes&#xff09;是一种向程序元素&#xff08;如类、方法、属性等&#xff09;添加元数据的方式。特性可以用来提供关于程序元素的附加信息&#xff0c;这些信息可以在编译时和运行时被访问。 特性主要有以下几个用途&#xff1a; 提…

北京交通大学《深度学习》专业课,实验2-前馈神经网络

1. 源代码 见资源“北京交通大学《深度学习》专业课&#xff0c;实验2-前馈神经网络” 2. 实验内容 &#xff08;1&#xff09;手动实现前馈神经网络解决上述回归、二分类、多分类任务 分析实验结果并绘制训练集和测试集的loss曲线 &#xff08;2&#xff09;利用to…

GUI界面开发之tkinter(一)

Tkinter是一个内置的Python库&#xff0c;用于创建图形用户界面&#xff08;GUI&#xff09;。它提供了一组工具和小部件&#xff0c;用于创建窗口、对话框、按钮、菜单和其他GUI元素。 在本篇文章中&#xff0c;主要介绍了窗口等知识点。 大家好&#xff01;我是码银&#x1…

STM32MP135裸机编程:烧录程序到EMMC的方法

0 前言 STM32MP135支持多种启动方式&#xff0c;包括SD卡、NAND Flash、EMMC等&#xff0c;基于STM32MP135裸机的SD卡烧录操作方法我们之前已经介绍过&#xff0c;现在介绍的STM32MP135烧录到EMMC的方法又和前面烧录到SD卡的操作有所不同。本文将介绍基于STM32MP135&#xff0…

缓存的击穿及解决方案

定义及图解 缓存击穿的意思是对于设置了过期时间的key&#xff0c;缓存在某个时间点过期的时 候&#xff0c;恰好这时间点对这个Key有大量的并发请求过来&#xff0c;这些请求发现缓存过期一般都会从后端 DB 加载数据并回设到缓存&#xff0c;这个时候大并发的请求可能会瞬间把…

Flutter 调用Google内购支付最新教程

前言: 各位同学大家好, 之前看到有人在群里问flutter 怎么调用Google支付, 今天就准备整理写一篇文章。 效果图 实现方式: 我们是通过flutter和安卓交互 然后在原生安卓里面加入了内购支付结算库的依赖 最后调起的Google 支付 安卓原生内购支付教程 flutter 端代码 我…

Go: IM系统开发及注意事项

概述 使用Go语言打造支持&#xff0c;同时十万人在线的IM系统系统单机支持十万人&#xff0c;如果分布式部署后&#xff0c;支持数百万都是可以的IM 系统&#xff0c; 即时通讯(Instant Messaging)&#xff0c;比如说我们的微信&#xff0c;QQ 等IM 系统&#xff0c;它具备非常…

软件测试服务公司分享:系统测试和验收测试有什么联系和区别?

软件系统测试是指对软件系统的各个模块、组件以及整个系统进行全面检查和验证的过程。它旨在检测系统的功能是否符合需求、是否能够正常运行以及是否存在潜在的问题。在软件开发的整个生命周期中&#xff0c;系统测试是一个非常重要且必不可少的环节。 软件验收测试是软件在开…

vs code 启动react项目,执行npm start报错原因分析

1.执行 npm start错误信息&#xff1a;npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确保路径正确&#xff0c;然后再试一次。 所在位置 行:1 字符: 1 npm start ~~~ CategoryInfo …

记录些Spring+题集(1)

接口防刷机制 接口被刷指的是同一接口被频繁调用&#xff0c;可能是由于以下原因导致&#xff1a; 恶意攻击&#xff1a;攻击者利用自动化脚本或工具对接口进行大量请求&#xff0c;以消耗系统资源、拖慢系统响应速度或达到其他恶意目的。误操作或程序错误&#xff1a;某些情…

【正点原子i.MX93开发板试用连载体验】录音小程序采集语料

本文最早发表于电子发烧友论坛&#xff1a;【新提醒】【正点原子i.MX93开发板试用连载体验】基于深度学习的语音本地控制 - 正点原子学习小组 - 电子技术论坛 - 广受欢迎的专业电子论坛! (elecfans.com) 接下来就是要尝试训练中文提示词。首先要进行语料采集&#xff0c;这是一…

C双指针元素去重

需求 在尾部插⼊、删除元素是⽐较⾼效的&#xff0c;时间复杂度 是 O(1)&#xff0c;但是如果在中间或者开头插⼊、删除元素&#xff0c;就会涉及数据的搬移&#xff0c;时间复杂度为 O(N)&#xff0c;效率较低。 代码 #include <stdio.h>// 相邻元素去重 int remove…