pytest fixture学习笔记

1前言

unittest中执行用例前后有setup,teardown操作,pytest中有fixture且比unittest更加灵活,
fixture具有明确的名称,并通过在测试函数、模块、类或整个项目中声明它们的使用来激活。
fixture是以模块化的方式实现的,因为每个fixture名称都会触发fixture函数,其本身也可以使用其他fixture。
fixture管理从简单的单元扩展到复杂的函数测试,允许根据配置和组件选项参数化fixture和测试,或者在函数、类、模块或整个测试会话范围内重复使用fixture。

2 fixture作用域

function:默认值,覆盖测试用例
class:测试类
module:整个py文件
session:夹的是收集到的所有测试用例

3 具体使用

3.1function级别

3.1.1代码实现

import pytest
@pytest.fixture(scope='function')
def init():
    print("开始执行测试用例")
    yield
    print("结束执行测试用例")


class TestCase:
    @pytest.mark.usefixtures("init")
    def test_aa(self):
        print("i am test_aa")
        assert 1==1

    def test_bb(self):
        print("i am test_bb")
        assert 2 == 2

if __name__ =="__main__":
    pytest.main(["-s","-v"])

其中yield前是执行用例前所需要执行的步骤,yield后是执行用例后所需要执行的步骤,如果有返回值,则是yield 返回值1,返回值2,多个返回值的话返回的是个元组

3.1.2返回结果

function.py                                                            [100%]

============================== 2 passed in 0.05s ==============================开始执行测试用例
.i am test_aa
结束执行测试用例
.i am test_bb

只有执行test_aa测试用例时执行了init方法

3.2 clsss级别

3.2.1代码实现

import pytest
@pytest.fixture(scope='class')
def init():
    print("开始执行测试用例")
    a,b=1,2
    yield a,b
    print("结束执行测试用例")


class TestCase:
    def test_aa(self,init):
        print("i am test_aa")
        assert init[0]==1

    def test_bb(self,init):
        print("i am test_bb")
        assert init[1] == 2

if __name__ =="__main__":
    pytest.main(["-s","-v"])

3.2.2返回结果

fixture_class.py 开始执行测试用例
.i am test_aa
.i am test_bb
结束执行测试用例
                                                      [100%]

============================== 2 passed in 0.08s ==============================
Process finished with exit code 0

即使所有的用例都使用了init方法,但只是在class执行前执行了init前置步骤,class执行后执行了init后置步骤
如果fixture没有返回结果,可以使用如下方法

@pytest.mark.usefixtures("init")
class TestCase:
    def test_aa(self):
        print("i am test_aa")
        assert 1==1

    def test_bb(self):
        print("i am test_bb")
        assert 2 == 2

if __name__ =="__main__":
    pytest.main(["-s","-v"])

3.3 moudle级别

整个py文件

3.3.1 代码实现

import pytest
@pytest.fixture(scope='module')
def init():
    print("开始执行测试用例")
    a,b=1,2
    yield a,b
    print("结束执行测试用例")

@pytest.mark.usefixtures("init")
class TestCase:
    def test_aa(self):
        print("i am test_aa")
        assert 1==1

    def test_bb(self):
        print("i am test_bb")
        assert 2 == 2

def test_cc():
    print("i am test_cc")
    assert 1 == 1

if __name__ =="__main__":
    pytest.main(["-s","-v"])

3.3.2 返回结果

fixture_module.py 开始执行测试用例
.i am test_aa
.i am test_bb
.i am test_cc
结束执行测试用例
                                                    [100%]

============================== 3 passed in 0.08s ==============================
Process finished with exit code 0

在整个py文件前执行了前置步骤,py文件执行完成后执行了后置步骤

3.4 session级别

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

3.4.1 代码实现

代码目录
在这里插入图片描述
conftest.py文件代码为

import pytest
@pytest.fixture(scope='session',autouse=True)
def init():
    print("开始执行测试用例")
    yield
    print("结束执行测试用例")
test_fixture_session.py文件代码

autouse是自动调用,即收集到的所有用例前都会执行
test_fixture_session.py文件代码

class TestCase:
    def test_aa(self):
        print("i am test_aa")
        assert 1==1

    def test_bb(self):
        print("i am test_bb")
        assert 2 == 2

test_fixture_session1.py文件代码

def test_cc():
    print("i am test_cc")
    assert 1 == 1

runall.py文件代码为

import pytest

pytest.main(["-s","-v","test_fixture_session.py","test_fixure_session1.py"])

执行runall.py

3.4.2 返回结果

collecting ... collected 3 items

test_fixture_session.py::TestCase::test_aa 开始执行测试用例
i am test_aa
PASSED
test_fixture_session.py::TestCase::test_bb i am test_bb
PASSED
test_fixure_session1.py::test_cc i am test_cc
PASSED结束执行测试用例
============================== 3 passed in 0.04s ==============================
Process finished with exit code 0

两个脚本执行前调用了init方法,输出开始执行测试用例,执行后输出结束执行测试用例

4 调用方法

从上面的例子中可以看出
如果需要使用fixture的返回值,那一定要传参,可以不用@pytest.mark.usefixtures("")
如果不需要使用fixture的返回值,一定要用@pytest.mark.usefixtures("")

5 源码解析

fixture源码详解

fixture(scope=‘function’,params=None,autouse=False,ids=None,name=None):

scope:有四个级别参数"function"(默认),“class”,“module”,“session”

params:一个可选的参数列表,它将导致多个参数调用fixture功能和所有测试使用它。

autouse:如果True,则为所有测试激活fixture func可以看到它。如果为False则显示需要参考来激活fixture

ids:每个字符串id的列表,每个字符串对应于params这样他们就是测试ID的一部分。如果没有提供ID它们将从params自动生成

name:fixture的名称。这默认为装饰函数的名称。如果fixture在定义它的统一模块中使用,夹具的功能名称将被请求夹具的功能arg遮蔽,解决这个问题的一种方法时将装饰函数命令"fixture_“然后使用”@pytest.fixture(name=’’)"。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值