单元测试界的高富帅,Pytest框架 (二) 前后置方法和 fixture 机制

news2024/11/25 18:43:54

前言

上一篇文章入门篇咱们介绍了pytest的基本使用,这一篇文章专门给大家讲解pytest中关于用例执行的前后置步骤处理,pytest中用例执行的前后置处理既可以通过测试夹具(fixtrue)来实现,也可以通过xunit 风格的前后置方法来实现。接下来我们一起看看如何具体使用。

一、xunit风格的前后置方法

1、函数用例的前后置方法

在模块中以函数形式定义用例,可以通过setup_function和teardown_function来定义函数用例的前后置方法,使用案例如下:

def setup_function(function):
    print("函数用例前置方法执行")

  
def teardown_function(function):
    print("函数用例后置方法执行")


def test_01():
    print('----用例方法01------')

运行结果:

C:\testcases>pytest -s
========================= test session starts =========================
platform win32 -- Python 3.7.3, pytest-5.4.2, py-1.8.0, pluggy-0.13.0 
cachedir: .pytest_cache
rootdir: C:\testcases
plugins:  testreport-1.1.2
collected 1 item                                                      
test_demo.py
函数用例前置方法执行
----用例方法01------ .
函数用例后置方法执行
========================= 1 passed in 0.27s =========================

2、测试类中用例的前后置方法

  • 类级别的前后置方法
  • pytest中测试类级别的前后置方法setup_class和teardown_class,分别在测试类中的用例执行之前执行,和测试类中所有用例执行完毕之后执行,具体使用如下:
  • class TestDome: def test_01(self): print('----测试用例:test_01------') def test_02(self): print('----测试用例:test_02------') @classmethod def setup_class(cls): print("测试类前置方法---setup_class---") @classmethod def teardown_class(cls): print("测试类后置方法---teardown_class---")
  • 用例级别的前后置方法
  • pytest中测试类中用例级别的的前后置方法setup_method和teardown_method,分别在测试类中的用例执行之前执行,和测试类中所有用例执行完毕之后执行,具体使用如下:
  • class TestDome: def test_01(self): print('----测试用例:test_01------') def test_02(self): print('----测试用例:test_02------') @classmethod def setup_class(cls): print("测试类前置方法---setup_class---") @classmethod def teardown_class(cls): print("测试类后置方法---teardown_class---") def setup_method(function): print("测试用例前置方法---setup_method---") def teardown_method(function): print("测试用例后置方法---teardown_method---")

运行结果:

C:\testcases>pytest -s
==================== test session starts ====================
platform win32 -- Python 3.7.3, pytest-5.4.2, py-1.8.0, pluggy-0.13.0
rootdir: C:\testcases
plugins:  testreport-1.1.2
collected 2 items                                                                                                                                 
test_demo.py 
测试类前置方法---setup_class---
测试用例前置方法---setup_method---
----测试用例:test_01------.
测试用例后置方法---teardown_method---
测试用例前置方法---setup_method---
----测试用例:test_02------.
测试用例后置方法---teardown_method---
测试类后置方法---teardown_class---

==================== 2 passed in 0.30s =======================

3、模块级别的前后置方法

pytest中还有setup_module和teardown_module这两个用来设置模块级别前后置方法的函数,定义在模块中,会在整个模块中所有的用例执行前和用例全部执行完毕之后会执行,具体使用如下:


class TestDome:

    def test_01(self):
        print('----测试用例:test_01------')


class TestDome2:

    def test_02(self):
        print('----测试用例:test_02------')
   
  
def setup_module(module):
    print("测试模块的前置方法---setup_module---")


def teardown_module(module):
    print("测试模块的前置方法---teardown_module---")

运行结果:

C:\testcases>pytest -s
====================== test session starts ====================== 
platform win32 -- Python 3.7.3, pytest-5.4.2, py-1.8.0, pluggy-0.13.0
rootdir: C:\testcases
plugins:testreport-1.1.2
collected 2 items                                                                   
test_demo.py 测试模块的前置方法---setup_module---
----测试用例:test_01------
.----测试用例:test_02------
.测试模块的前置方法---teardown_module---
====================== 2 passed in 0.27s ====================== 

二、fixture机制

前面我们介绍了pytest中xunit风格的前后置方法,接下来我们来看一下pytest中功能更加强大的fixture机制(测试夹具)的使用。

1、测试夹具的级别和定义

测试夹具需要使用pytest.fixture这个装饰器来定义,pytest中的测试夹具有如下几个级别:用例级别、测试类级别、模块级别,包级别,会话级别。接下来我们一起来看看夹具定义语法。

夹具定义可以通过参数scope指定夹具的级别,如果不指定夹具级别,scope 默认值为function(用例级别)

用例级别:scope = function

测试类级:scope = class

模块级别:scope = module

包级别: scope = package

会话级别:scope = session

@pytest.fixture(scope='指定夹具的级别')
def work():
    # 前置执行脚本
    yield 
    # 后置执行脚本

测试夹具本质上是一个生成器函数,生产器函数在使用next进行迭代时,执行到yeild会返回数据,暂停执行,等待下一次进行迭代时才会继续执行,pytest夹具就是利用的生成器的机制,通过yeild在测试夹具将前后置代码分开执行。

注意点: 夹具只有在定义夹具的范围内才能使用。如果夹具是在类中定义的,则只能由该类内的测试用例使用。但是如果在模块的全局范围内定义的夹具,那么该模块中的每个测试用例,即使它是在一个类中定义的,都可以使用它。

知道了怎么定义夹具,那么接下来我们来看看如何使用夹具。

2、夹具的使用

测试夹具定义好之后,测试函数通过将它们声明为参数,来指定执行用例之前要执行的夹具。

当 pytest 开始运行测试时,它会查看该测试函数定义的形参,然后搜索与这些参数同名的测试夹具。一旦 pytest 找到它们,它就会运行这些夹具,接收它们返回的内容(如果有的话),并将这些返回内容作为参数传递给测试函数。

注意点:当我们使用夹具时,如果夹具的前置脚本执行完,有数据要传递用例,需要传递的数据写在yield后面即可,在使用夹具的用例或者方法中,可以通过定义的形参来获取yeild返回的数据(章节2.3中有使用案例介绍)

2.1、在用例中使用夹具

不管是函数形式定义的测试用例,还是测试类中方法的形式定义的用例,在使用的时候都是一样的,直接定义一个和要使用的夹具同名的形参即可。

import pytest

# 定义一个用例级别的夹具
@pytest.fixture
def my_fixture():
    print('------my_fixture---用例前置执行脚本--------')
    yield
    print('------my_fixture---用例后置执行脚本--------')

# 函数用例 指定测试夹具
def test_func__01(my_fixture):
    print("测试用例----test_func__01----")


class TestDome:
    # 函数用例 指定测试夹具
    def test_02(self, my_fixture):
        print('----测试用例:test_02------')
  
     # 函数用例 指定测试夹具
    def test_03(self):
        print('----测试用例:test_03------')

运行结果

C:\testcases>pytest -s
======================== test session starts ========================
platform win32 -- Python 3.7.3, pytest-5.4.2, py-1.8.0, pluggy-0.13.0
rootdir: C:\testcases
plugins: testreport-1.1.2
collected 2 items  
test_demo.py 
------my_fixture---前置执行脚本--------
测试用例----test_func__01----.
------my_fixture---后置执行脚本--------
------my_fixture---前置执行脚本--------
----测试用例:test_02------.
------my_fixture---后置执行脚本--------
----测试用例:test_03------
======================== 2 passed in 0.27s ========================

上面test_func__01和test_02这两个用例在定义时指定了测试夹具,而test_03则没有指定执行的夹具,执行用例时库看到指定了夹具的用例,执行了对应的夹具。

2.2、测试类和模块指定夹具

上面我们通过给用例方法加形参来给单个测试用例指定测试夹具。如果一个测试类中有很多测试用例或者一个模块中有很多用例,都要指定同一个测试夹具,要我们则可以通过usefixtures给测试类或测试模块指定测试夹具。

给测试类中所有的用例指定夹具

# TestDome这个测试类的所有测试用例均执行my_fixture这个夹具
@pytest.mark.usefixtures('my_fixture这个夹具')
class TestDome:
    # 函数用例 指定测试夹具
    def test_02(self):
        print('----测试用例:test_01------')

    # 函数用例 指定测试夹具
    def test_03(self):
        print('----测试用例:test_02------')

使用pytestmark 在测试模块级别 指定模块所有用例执行的夹具

# test_demo.py

# 当前模块中所有的用例,均执行my_fixture这个测试夹具
pytestmark = pytest.mark.usefixtures('my_fixture')

# 函数用例 指定测试夹具
def test_func__01(my_fixture):
    print("测试用例————test_func__01——————")

  
class TestDome:
    # 函数用例 指定测试夹具
    def test_02(self):
        print('----测试用例:test_01------')

    # 函数用例 指定测试夹具
    def test_03(self):
        print('----测试用例:test_02------')

2.3、在夹具中引用夹具

pytest 的最大优势之一是其极其灵活的夹具系统。通过测试夹具我们可以将极为复杂化的前后置依赖,拆分为更简单单一功能的测试夹具,通过在夹具中引用其他的夹具,来组织不同用例所需的复杂依赖环境。接下来我们通过一个案例来给大家演示如何使用。

import pytest
# 用户注册的夹具
@pytest.fixture
def register_user():
    print('---用户注册的夹具前置执行----')
    # ...注册代码省略,注册的用户信息如下
    user_info = {'user': 'lemonban', 'pwd': '123456'}
    yield user_info
    print('---用户注册的夹具后置执行----')


# 用户登录的夹具,通过定义形参来使用register_user这个夹具
@pytest.fixture
def user_login(register_user):
    print('---用户登录的夹具前置执行----')
    # 获取register_user结局前置脚本执行完,yeild传递出来的数据
    user_info = register_user
    # ...登录代码省略,下面为登录得到的token
    token = 'sdjasjdask'
    yield token
    print('---用户登录的夹具后置执行----')

# 函数用例 指定使用测试夹具user_login
def test_func__01(user_login):
    token = user_login
    print("测试用例夹具user_login传递过来的token:",token)
    print("测试用例---test_func__01---")

运行结果

C:\testcases>pytest -s
======================== test session starts ========================
platform win32 -- Python 3.7.3, pytest-5.4.2, py-1.8.0, pluggy-0.13.0
rootdir: C:\testcases
plugins: testreport-1.1.2
collected 1 item  
test_demo.py 
---用户注册的夹具前置执行----
夹具register_user传递过来的用户信息: {'user': 'lemonban', 'pwd': '123456'}
---用户登录的夹具前置执行----
测试用例夹具user_login传递过来的token: sdjasjdask
测试用例---test_func__01---.
---用户登录的夹具后置执行----
---用户注册的夹具后置执行----

2.4、自动使用夹具

在定义测试夹具 我们可以给夹具的装饰器加参数autouse=True来使夹具成为自动执行的夹具。具体案例如下:

import pytest


@pytest.fixture(autouse=True)
def my_fixture():
    print('------my_fixture---前置执行脚本--------')
    yield
    print('------my_fixture---后置执行脚本--------')


class TestDome:
    # 函数用例 指定测试夹具
    def test_02(self):
        print('----测试用例:test_01------')

    # 函数用例 指定测试夹具
    def test_03(self):
        print('----测试用例:test_02------')


class TestDome2:
    # 函数用例 指定测试夹具
    def test_03(self):
        print('----测试用例:test_03------')

执行结果:

C:\testcases>pytest -s
======================== test session starts ========================
platform win32 -- Python 3.7.3, pytest-5.4.2, py-1.8.0, pluggy-0.13.0
rootdir: C:\testcases
plugins: testreport-1.1.2
collected 3 items    
test_demo.py
------my_fixture---前置执行脚本--------
----测试用例:test_01------.
------my_fixture---后置执行脚本--------
------my_fixture---前置执行脚本--------
----测试用例:test_02------.
------my_fixture---后置执行脚本--------
------my_fixture---前置执行脚本--------
----测试用例:test_03------.
------my_fixture---后置执行脚本--------
======================== 3 passed in 0.29s ========================

从上面的执行结果我们可以看到,每条用例执行之前都自动执行了测试夹具my_fixture

3、conftest.py

在一个项目的测试中,大多数情况下会有多个类、模块、或者包要使用相同的测试夹具。这种情况下如果我们把测试夹具定义在某一个模块中则无法实现共享,针对这种情况,我们可以把需要共享的测试夹具放入一个单独的conftest.py文件中 ,这样多个可以实现多个测试模块共享了

ps : pytest运行测试时,如果项目中有conftest.py,那么pytest会自动加载conftest.py模块中的内容,可以把conftest看出pytest会自动加载的插件模块,后续的教程中会涉及到在conftest.py中定义pytest的hooks函数

接下来我们来看一个conftest.py定义测试夹具的案例

在 conftest.py中定义测试夹具my_fixture

# conftest.py

import pytest

@pytest.fixture
def my_fixture():
    print('------my_fixture---前置执行脚本--------')
    yield
    print('------my_fixture---后置执行脚本--------')

在test_demo1.py的用例用使用conftest.py中定义的夹具

# test_demo1.py
class TestDome:
    # 函数用例 指定测试夹具
    def test_02(self,my_fixture):
        print('----测试用例:test_01------')

    # 函数用例 指定测试夹具
    def test_03(self,my_fixture):
        print('----测试用例:test_02------')

在test_demo2.py的用例用使用conftest.py中定义的夹具

# test_demo2.py
class TestDome2:
    # 函数用例 指定测试夹具
    def test_03(self,my_fixture):
        print('----测试用例:test_03------')

执行结果:

C:\testcases>pytest -s
======================== test session starts ========================
platform win32 -- Python 3.7.3, pytest-5.4.2, py-1.8.0, pluggy-0.13.0
rootdir: C:\testcases
plugins: testreport-1.1.2
collected 3 items
test_demo.py 
------my_fixture---前置执行脚本--------
----测试用例:test_01------.
------my_fixture---后置执行脚本--------
------my_fixture---前置执行脚本--------
----测试用例:test_02------.
------my_fixture---后置执行脚本--------
test_demo2.py 
------my_fixture---前置执行脚本--------
----测试用例:test_03------.
------my_fixture---后置执行脚本--------
======================== 3 passed in 0.29s ========================

上述案例中我们可以发现 est_demo.py和est_demo2.py中的用例可以成功使用conftest.py中的测试用例。

下一篇跟大家讲解用例标记跟测试执行
下面是我当时学习时用过的部分资料,有需要的朋友可以评论区留言

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

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

相关文章

利用procrank和lsof定位出客户软件内存OOM的问题

最近遇到一些事情,觉得挺憋屈的,可是再憋屈总得往前走吧!打工人,不好办啊!事情是这样的,笔者在芯片原厂负责SDK和行业解决方案输出的,可以理解成整体SDK turnkey方案。但是有些客户多少还要改一…

单例模式(饿汉式单例 VS 懒汉式单例)

所谓的单例模式就是保证某个类在程序中只有一个对象 一、如何控制只产生一个对象? 1.构造方法私有化(保证对象的产生个数) 创建类的对象,要通过构造方法产生对象 构造方法若是public权限,对于类的外部,可…

企业架构LNMP学习笔记31

负载均衡服务器的高可用备用服务器配置: 负载均衡服务器的配置比单台服务器的配置要高很多。硬件上要上一个台阶。 所有的请求流量都要经过负载均衡服务器,负载均衡服务器压力很大,防止她宕机,导致后端web服务器都不可用&#xf…

ROS2下使用TurtleBot3-->SLAM导航(仿真)RVIZ加载不出机器人模型

一、问题描述 在使用台式机进行仿真时,大部分例程很顺利,但在SLAM导航时,在RVIZ中却一直加载不出机器人模型,点击Navigation2 Goal选择目标点进行导航时,无响应。 启动后在RVIZ2和终端看到一个错误 按照官网的指令试…

探索 Wall-E 的寻路算法

几年前,Yandex 组织了一场名为“机器人快递员”的竞赛,并提供了诱人的奖品:一张参加专业人士封闭式自动驾驶会议的门票。该竞赛类似于一场游戏,参与者的任务是在地图上找到最佳路线并使用机器人快递员优化送货。 当我深入研究这个主题时,我发现尽管路线查找问题已经解决,…

ms17-010(永恒之蓝)漏洞复现

目录 前言 一、了解渗透测试流程 二、使用nmap工具对win7进行扫描 2.1 2.2 2.3 2.4 2.5 三、尝试ms17-010漏洞利用 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 四、结果展示 4.1 4.2 4.3 4.4 4.5 总结 前言 ms17-010(永恒之蓝&am…

mysql八股1

参考MySQL八股文连环45问(背诵版) - 知乎 (zhihu.com) 基础 1.范式 第一范式:强调的是列的原子性 第二范式:要求实体的属性完全依赖于主关键字。所谓完全 依赖是指不能存在仅依赖主关键字一部分的属性。(就是主键不…

Linux防火墙(iptables)

一、linux的防火墙组成 linux的防火墙由netfilter和iptables组成。用户空间的iptables制定防火墙规则,内核空间的netfilter实现防火墙功能。 netfilter(内核空间)位于Linux内核中的包过滤防火墙功能体系,称为Linux防火墙的“内核…

Vulnhub:Kira: CTF靶机

kali:192.168.111.111 靶机:192.168.111.238 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.238访问80端口 点击upload发现是个上传点 点击language发现存在文件包含 上传php图片马再利用文件包含反弹shell http://1…

CIO40: 数字化落地最佳实践(16000字)

1-数字化规划 第一步:数字化规划。CIO要根据企业的发展现况及未来战略方向、根据企业董事长的布局和理念、根据企业各业务板块领导人的格局和理念,做出一份董事长和领导层高度认同的数字化规划,而且需要用PPT进行完整和专业的表达出来&#x…

基于SpringBoot的在线教育平台系统

基于SpringBootVue的线教育平台系统,前后端分离 开发语言:Java数据库:MySQL技术:SpringBoot、Vue、Mybaits Plus、ELementUI工具:IDEA/Ecilpse、Navicat、Maven 【主要功能】 角色:管理员、学生、老师 …

When后接什么动词?

1、when doing用法 When从句的主语和主句的主语是同一个或同一些人时,从句的谓语动词为be动词doing形式,可以把从句的主语和be动词省略,即用when doing sth是指当做……事情时, 如: when doing the work,we should b…

(以太网交换机)BCM53575B0KFSBG、BCM56870A0KFSBG、BCM56760B0KFSBG采用BGA封装的集成电路

一、BCM53575B0KFSBG 1G/2.5G/10G/25G TSN 连接交换机 应用 中小企业 2.5G/10G 交换机 使用时间敏感网络(TSN)的工业以太网/汽车应用 联网 (TSN) 的工业以太网/汽车应用 用于基站、闪存阵列、专业级音频/视频和机箱背板的嵌入式连接交换机 (…

自然语言处理NLP:一文了解NLP自然语言处理技术,NLP在生活中的应用,图导加深了解,NLP语料库,NLP开源工具

目录 1.自然语言处理NLP 1.1 NLP中英对照(双份) 1.2 相关文章 2.NLP语料库 2.1 NLP语料库列举 2.2 相关文章 3.NLP开源工具 3.1 NLP开源工具列举 3.2 相关文章 4.自然语言文本分类模型代码 5.图导NLP 6. NLP在生活中的应用 1.自然语言处理NLP …

Kafka中Consumer源码解读

Consumer源码解读 本课程的核心技术点如下: 1、consumer初始化 2、如何选举Consumer Leader 3、Consumer Leader是如何制定分区方案 4、Consumer如何拉取数据 5、Consumer的自动偏移量提交 Consumer初始化 从KafkaConsumer的构造方法出发,我们跟踪到…

ubuntu22.04 设置网卡开机自启

配置文件路径 在Ubuntu中,网络配置文件通常位于/etc/netplan/目录下,其文件名以.yaml为后缀。Netplan是Ubuntu 17.10及更高版本中默认的网络配置工具,用于配置网络接口、IP地址、网关、DNS服务器等。 我们可以看到配置文件为 01-network-ma…

【K210+ESP8266图传上位机开发】TCP server + JPEG图像解析上位机开发

本文章主要记录基于 【K210-ESP8266】 图传和显示的过程,上位机开发过程,系统架构和下位机开发请参考文章: 【K210-ESP8266】开发板上传图像数据到服务器并实时显示 💖 作者简介:大家好,我是喜欢记录零碎知…

easyrecovery 2023最新数据恢复软件免费下载激活教程

对于每天电脑不离身,键盘不离手的法律人来说,最惨痛的事故莫过于“没保存”了,意外断电、系统崩溃、介质故障、计算机病毒、文件误删除、系统升级、文件同步更新、程序运行意外中止、人为故意删改等各种原因都可能导致我们的文件数据损坏和丢…

eNSP-抓包实验

拓扑结构图: 实验需求: 1. 按照图中的设备名称,配置各设备名称 2. 按照图中的IP地址规划,配置IP地址 3. 使用Wireshark工具进行抓ping包,并分析报文 4. 理解TCP三次握手的建立机制 实验步骤: 1、配置P…

synchronized,volatile关键字

目录 一,synchronized的特性 1.1 互斥性 1.2 可重入性 二, 死锁 2.1 死锁产生的原因 三,volatile 关键字 3.1 能保证内存可见性 一,synchronized的特性 1.1 互斥性 当两个线程对同一个对象加锁时,后加锁的线程…