首页 > 其他分享 >超详细的 pytest 教程 (三) 之前后置方法和 fixture 机制

超详细的 pytest 教程 (三) 之前后置方法和 fixture 机制

时间:2023-07-19 11:35:25浏览次数:37  
标签:后置 fixture --- 用例 pytest test ------ 夹具

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

一、xunit风格的前后置方法

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

  • 在模块中以函数形式定义用例,可以通过setup_functionteardown_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、测试类中用例的前后置方法

2.1、类级别的前后置方法
  • 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---")
2.2、用例级别的前后置方法
  • 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(用例级别)
  1. 用例级别:scope = function
  2. 测试类级:scope = class
  3. 模块级别:scope = module
  4. 包级别: scope = package
  5. 会话级别:scope = session
  • 用法:
@pytest.fixture(scope='指定夹具的级别')
def work():
    # 前置执行脚本
    yield 
    # 后置执行脚本
  • 测试夹具本质上是一个生成器函数,生产器函数在使用next进行迭代时,执行到yeild会返回数据,暂停执行,等待下一次进行迭代时才会继续执行,pytest夹具就是利用的生成器的机制,通过yeild在测试夹具将前后置代码分开执行。
  • 注意点: 夹具只有在定义夹具的范围内才能使用。如果夹具是在类中定义的,则只能由该类内的测试用例使用。但是如果在模块的全局范围内定义的夹具,那么该模块中的每个测试用例,即使它是在一个类中定义的,都可以使用它。
  • 知道了怎么定义夹具,那么接下来我们来看看如何使用夹具。

2、夹具的使用

  • 测试夹具定义好之后,测试函数通过将它们声明为参数,来指定执行用例之前要执行的夹具。
  • 当 pytest 开始运行测试时,它会查看该测试函数定义的形参,然后搜索与这些参数同名的测试夹具。一旦 pytest 找到它们,它就会运行这些夹具,接收它们返回的内容(如果有的话),并将这些返回内容作为参数传递给测试函数。
  • 注意点:当我们使用夹具时,如果夹具的前置脚本执行完,有数据要传递用例,需要传递的数据写在yield后面即可,在使用夹具的用例或者方法中,可以通过定义的形参来获取yeild返回的数据
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、测试类和模块指定夹具
  • 上面我们通过给用例方法加形参来给单个测试用例指定测试夹具。如果一个测试类中有很多测试用例或者一个模块中有很多用例,都要指定同一个测试夹具,要我们则可以通过需求1:给测试类中所有的用例指定夹具usefixtures给测试类或测试模块指定测试夹具。
  • 需求1:给测试类中所有的用例指定夹具
import pytest

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

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

    # 函数用例 指定测试夹具
    def test_03(self):
        print('----测试用例:test_02------')
  • 运行结果:
D:\Pycharm_workspace>pytest -v -s test_login.py
================================================= test session starts =================================================
platform win32 -- Python 3.10.10, pytest-7.3.1, pluggy-1.0.0 -- D:\software\Python310\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.10.10', 'Platform': 'Windows-10-10.0.19045-SP0', 'Packages': {'pytest': '7.3.1', 'pluggy': '1.0.0'}, 'Plugins': {'allure-pytest': '2.13.2', 'Faker': '18.10.1', 'base-url': '2.0.0', 'html': '3.2.0', 'metadata': '3.0.0', 'playwright': '0.3.3', 'testreport': '1.1.6'}, 'JAVA_HOME': 'D:\\software\\Program Files\\Java\\jdk-11.0.12'}
rootdir: D:\Pycharm_workspace\py63\d3_0719_python数据类型_列表与元组
plugins: allure-pytest-2.13.2, Faker-18.10.1, base-url-2.0.0, html-3.2.0, metadata-3.0.0, playwright-0.3.3, testreport-1.1.6
collected 2 items

test_login.py::TestDome::test_02 ------my_fixture---用例前置执行脚本--------
----测试用例:test_01------
PASSED------my_fixture---用例后置执行脚本--------

test_login.py::TestDome::test_03 ------my_fixture---用例前置执行脚本--------
----测试用例:test_02------
PASSED------my_fixture---用例后置执行脚本--------


================================================== 2 passed in 0.10s ==================================================
  • 上面TestDome类中test_02和test_03使用了测试夹具

 

  • 需求2:使用pytestmark 在测试模块级别 指定模块所有用例执行的夹具
import pytest

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

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

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

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

    # 函数用例 指定测试夹具
    def test_03(self):
        print('----测试用例:test_02------')
  • 运行结果:
D:\Pycharm_workspace>pytest -v -s test_login.py
================================================= test session starts =================================================
platform win32 -- Python 3.10.10, pytest-7.3.1, pluggy-1.0.0 -- D:\software\Python310\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.10.10', 'Platform': 'Windows-10-10.0.19045-SP0', 'Packages': {'pytest': '7.3.1', 'pluggy': '1.0.0'}, 'Plugins': {'allure-pytest': '2.13.2', 'Faker': '18.10.1', 'base-url': '2.0.0', 'html': '3.2.0', 'metadata': '3.0.0', 'playwright': '0.3.3', 'testreport': '1.1.6'}, 'JAVA_HOME': 'D:\\software\\Program Files\\Java\\jdk-11.0.12'}
rootdir: D:\Pycharm_workspace\py63\d3_0719_python数据类型_列表与元组
plugins: allure-pytest-2.13.2, Faker-18.10.1, base-url-2.0.0, html-3.2.0, metadata-3.0.0, playwright-0.3.3, testreport-1.1.6
collected 3 items

test_login.py::test_func__01 ------my_fixture---用例前置执行脚本--------
测试用例————test_func__01——————
PASSED------my_fixture---用例后置执行脚本--------

test_login.py::TestDome::test_02 ------my_fixture---用例前置执行脚本--------
----测试用例:test_01------
PASSED------my_fixture---用例后置执行脚本--------

test_login.py::TestDome::test_03 ------my_fixture---用例前置执行脚本--------
----测试用例:test_02------
PASSED------my_fixture---用例后置执行脚本--------


================================================== 3 passed in 0.10s ==================================================
  • test_login.py模块中所有用例都使用了测试夹具
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文件中 ,这样多个可以实现多个测试模块共享了
  • 注意点 : pytest运行测试时,如果项目中有conftest.py,那么pytest会自动加载conftest.py模块中的内容,可以把conftest看出pytest会自动加载的插件模块,后续的教程中会涉及到在conftest.py中定义pytest的hooks函数
  • 接下来我们来看一个conftest.py定义测试夹具的案例
  1. conftest.py中写夹具 
# conftest.py

import pytest

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

      2. 在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------')

  3. 在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 ========================
  • 上述案例中我们可以发现 test_demo.py和test_demo2.py中的用例可以成功使用conftest.py中的测试用例。

标签:后置,fixture,---,用例,pytest,test,------,夹具
From: https://www.cnblogs.com/xiaoxiao-wu/p/17565077.html

相关文章

  • 超详细的 pytest 教程 (二) 之测试报告篇
    这个章节主要给大家介绍pytest如何集成测试报告。pytest本身是没有生成测试报告的功能,但是pytest中有很多插件,我们可以通过插件来生成测试报告。下面会给大家介绍两个生成报告的方式。一个是生成html报告,一个是集成allure报告平台来展示测试报告。一、生成HTML报告1.1、安装......
  • 超详细的 pytest 教程(一)使用入门篇
    前言pytest到目前为止还没有翻译的比较好全面的使用文档,很多英文不太好的小伙伴,在学习时看英文文档还是很吃力。本来去年就计划写pytest详细的使用文档的,由于时间关系一直搁置,直到今天才开始写。本文是第一篇,主要介绍pytest的入门使用,后续会分篇针对pytest中的各个功能出详细的......
  • pytest测试实战
    电子pdf下载链接:目录: ......
  • PlayWright(十九)- Pytest之fixture测试夹具
    fixture是Pytest的测试夹具,相当于unittest的setup和teardown,这个在之前我们也有介绍setup和teardown详情可看:https://www.cnblogs.com/nuomituan/p/17541815.html  那为什么我们不用setup和teardown呢,因为我们使用fixture更加灵活,具体有独立的命名,然后呢,还可以按模块化的方......
  • pytest + yaml 框架 -52.支持 websocket 协议
    前言v1.4.2版本支持websocket协议python操作websocket协议环境准备pip3installwebsocket-clientpip3installwebsockets基本代码示例fromwebsocketimportcreate_connectionimportjsonurl='ws://localhost:8081/ws'ws=create_connection(url,timeout......
  • 2. pytest框架环境搭建
      1.安装pytest1安装pytest:pippytest23三方插件:45pipinstallXXX67pytest-xdist(分布式测试)8pytest-selenium(集成selenium)9pytest-html(完美html测试报告---原生态)10pytest-rerunfailures(失败case重复执行)11pytest-forked12allure-pyte......
  • pytest---更改自动化测试用例执行顺序
    前言在自动化测试中,自动化测试用例设计原则就是执行过程时不能存在依赖顺序,那么如果测试用例需要按照指定顺序执行,这个时候应该怎么做呢?目前单元测试框架中unittest没有办法改变测试用例的执行顺序,但是另一个单元测试框架pytest可以做到,辅助测试人员更改测试用例的执行顺序,今天小......
  • PlayWright(十六)- Pytest断言
    我们在写自动化测试的时候,得到测试结果之后,现在要开始拿实际结果与期望结果做对比了 那如果是测试1个结果,我们可以用肉眼比对,如果是百十来个用例结果,我们肉眼就看不过来了,所以我们需要断言,而在Pytest中也有断言,而且Pytest的断言使用的是Python自带的,所以使用起来很方便 使......
  • AEE P2随身记录仪:180°翻转镜头,后置摄像头秒变前置
    DSJ-P2为AEE推出的新款随身音视频记录仪,主打小巧便携,整机尺寸只有104*35*17mm,净重仅58g,非常适合长时间随身携带的用户。除了小巧轻薄之外,P2的最大亮点就是拥有一颗可180度翻转摄像头,既让P2外观更加简约,又解决了前置摄像头像素不足的问题。搭配4800万拍照像素和1080P高清摄录,支持120......
  • pytest生成测试报告无数据
    1、排除用pytest生成的数据是没有问题的可以通过pytest--alluredir=report检查2、了解使用的语句:alluregeneratereport(用report文件夹中的数据,生成allure打开的图形界面的)我操作的失误在第二点,直接进入到report文件夹执行。导致生成的项目的时候,数据没有被读取。解决方案:......