Pytest自动化测试fixture之conftest.py

本文深入讲解pytest中的fixture机制,对比setup与teardown方法,fixture提供了更灵活的命名、数据共享及不同作用域的支持,适用于自动化测试中复杂前置条件的设置。

之前我们讲到用例前后置方法 [ setup 、teardown ] Pytest测试用例之setup与teardown方法(一)  Pytest测试用例之setup与teardown方法(二) 可以实现在自动化测试用例执行前或执行后进行特定的操作

但是不足之处是 [ setup 、teardown ] 只满足在全局或者每条case前、后。不能满足A测试用例执行,B测试用例不执行,那么我们还有什么方法能够实现这自定义的场景呢 

来看看我们今天的猪脚fixture

01前言

fixture优势

[ firture相对于setup与teardown来说应该有以下几点优势 ]

1.命名方式灵活,不限于setup与teardown这几个命名

2.conftest.py 配置里可以实现数据共享,不需要import就能自动找到一些配置

3.scope="module" 可以实现多个.py跨文件共享前置

4.scope="session" 以实现多个.py跨文件使用一个session来完成多个用例

fixture介绍

fixture(scope="function", params=None, autouse=False, ids=None, name=None):
    """使用装饰器标记fixture的功能
     可以使用此装饰器(带或不带参数)来定义fixture功能。fixture功能的名称可以在以后使用
     引用它会在运行测试之前调用它:test模块或类可以使用pytest.mark.usefixtures(fixturename标记。
     测试功能可以直接使用fixture名称作为输入参数,在这种情况下,夹具实例从fixture返回功能将被注入。


    :arg scope: scope 有四个级别参数 "function" (默认), "class", "module" or "session".


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


    :arg autouse:  如果为True,则为所有测试激活fixture func 可以看到它。如果为False(默认值)则显式需要参考来激活fixture


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


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

02 fixture实战代码

实现场景:例如我们实际项目中登录有case执行前与case执行后俩种测试用例,那么我们该用什么方法去设计这种呢?

例如第一条测试用例需要执行登录,第二条测试用例不需要执行,第三条测试用例需要执行,看看实现的代码

# coding=utf-8
# authou:shichao
# python测试社区学习记录




import pytest




# 不带参数时默认scope='function' 如果@pytest.fixture()里面没有参数,那么默讣 scope=”
# function”,也就是此时的级别的 function,针对函数有效
@pytest.fixture()
def login():
    print('前置进行输入账号密码登录')




def test_a1(login):
    print('执行测试用例1,继承login函数、前置登录后,继续下一步操作')




def test_a2():  # 不传login
    print('用例2 不需要登录,做其他动作')




def test_a3(login):  # 不传login
    print('执行测试用例3,继承login函数、 前置登录后,继续下一步操作')




if __name__ == '__main__':
    pytest.main(['-s', 'test_fix_0708.py'])

运行结果

rootdir: F:\python3\python_code\Study\API_AutoTest_Pytest
collecting ... collected 3 items


test_fix_0708.py::test_a1 前置进行输入账号密码登录
PASSED                                         [ 33%]执行测试用例1,继承login函数、前置登录后,继续下一步操作


test_fix_0708.py::test_a2 PASSED                                         [ 66%]用例2 不需要登录,做其他动作


test_fix_0708.py::test_a3 前置进行输入账号密码登录
PASSED                                         [100%]执行测试用例3,继承login函数、 前置登录后,继续下一步操作




============================== 3 passed in 0.02s ==============================


Process finished with exit code 0

总结:如果@pytest.fixture()里面没有参数,那么默认scope=”function”,也就是此时的级别的function,针对函数有效

03 conftest.py配置

上面一个案例是在同一个.py文件中,多个用例调用一个登录功能,如果有多个.py的文件都需要调用这个登陆功能的话,那就不能把登录写到用例里面去了。

此时应该要有一个配置文件,单独设计管理一些预置的操作场景,在pytest里面是默认读取conftest.py里面的配置

conftest.py配置需要注意以下点:

1.conftest.py配置脚本名称是固定的,不能改名称

2.conftest.py与运行的用例要在同一个pakage下,并且有init.py文件

3.不需要import导入 conftest.py,pytest用例会自动查找

以下分别是新建三个文件conftest.py、test_fix_0708_01.py、test_fix_0708_02.py

# coding =utf-8
# authou:shichao
# python测试社区记录#
'''
conftest.py 配置需要注意以下点:
conftest.py 配置脚本名称是固定的,丌能改名称
conftest.py 不运行的用例要在同一个 pakage 下,并且有
__init__.py 文件
不需要 import 导入 conftest.py,pytest 用例会自动查找
'''


import pytest




@pytest.fixture()
def login():
    print('输入账号,密码先登录')
# coding=utf-8


import pytest




def test_a1(login):
    print('执行测试用例1,继承login函数、前置登录后,继续下一步操作')




def test_a2():
    print('执行测试用例2,不需要登录,继续下一步操作')




def test_a3(login):
    print('执行测试用例3,继承login函数、前置登录后,,继续下一步操作')




if __name__ == '__main__':
    pytest.main(['-s', 'test_fix_0708_01.py'])
# coding=utf-8


import pytest




def test_a4(login):
    print("用例4:继承login函数、前置登录后,继续下一步操作")




def test_a5():  # 不传login
    print("用例5:不需要登录,继续下一步操作")




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


总结:单独运行test_fix1.py与test_fix2.py都能调用到login()方法,这样就能实现一些公共的操作可以单独拿出来

fixture之conftest.py本期分享到这里简单告一段落,后期再总结分享,关注小编查看更多测试好文,学到各种测试小知识点

从0到1, 将APP自动化测试入个门 /《Linux 命令行大全》测试必备

<think>我们有一个关于pytestfixture的问题,特别是如何在conftest.py中定义一个全局fixture并设置autouse=True。 根据引用[1]和[2],我们知道conftest.pypytest的配置文件,用于放置fixture,并且可以被多个测试文件共享。同时,fixture的autouse参数可以设置为True,这样fixture会自动在每个测试用例中执行,而不需要显式引用。 步骤: 1. 创建conftest.py文件:在项目的根目录(或者需要全局生效的目录)下创建一个名为conftest.py的文件。 2.conftest.py中定义fixture,并设置autouse=True。 3. 根据引用[2]中的说明,conftest.py的作用范围是它同级目录及其子目录。因此,为了全局生效,通常将conftest.py放在项目的根目录下。 示例代码: 假设我们想要一个在每个测试用例之前自动打印开始日志,之后打印结束日志的fixture,我们可以这样写: 在conftest.py中: ```python import pytest @pytest.fixture(autouse=True) def global_fixture(): # 在每个测试用例开始前执行的部分 print("\n=== 测试开始 ===") yield # 这里yield表示测试用例执行的时机 # 在每个测试用例结束后执行的部分 print("\n=== 测试结束 ===") ``` 注意: - 使用`autouse=True`意味着这个fixture会自动应用于所有作用域内的测试用例,不需要在测试用例中显式使用。 - 这个fixture的作用域(scope)默认是function,即每个测试函数都会执行一次。如果需要改变作用域,可以设置scope参数,例如`@pytest.fixture(autouse=True, scope="session")`。 另外,引用[3]中提到conftest.py的核心功能之一是测试夹具(Fixtures)的集中管理,所以我们可以把多个fixture放在这里。 但是,要注意多个autouse fixture的执行顺序: 1. 相同作用域下,autouse fixture按照定义的顺序执行(先定义的先执行)。 2. 不同作用域下,执行顺序为:session > module > class > function(作用域大的先执行)。 因此,在定义多个autouse fixture时,要注意它们之间的依赖关系和执行顺序。 问题:如果我们在不同的conftest.py中定义了autouse fixture,那么根据引用[2]中的“搜索优先级自底而上”和“就近原则”,同名的fixture会使用更近的(即子目录中的)conftest.py中的定义。但是,如果多个conftest.py中的autouse fixture不同名,那么它们都会生效,且按照作用域和定义顺序执行。 总结:在项目根目录的conftest.py中定义一个fixture,并设置autouse=True,即可实现全局自动使用。 生成相关问题: 1. 如何控制多个autouse fixture的执行顺序? 2.conftest.py中定义的fixture如何传递参数? 3. 如何在不同作用域(如session, module)使用autouse fixture? 4. 如果子目录的conftest.py中也有autouse fixture,它与根目录的conftest.py中的autouse fixture如何交互?</think>### 在 pytest 中定义全局 autouse fixture 在 `conftest.py` 中定义全局自动生效的 fixture 需遵循以下步骤: #### 1. 创建配置文件 在项目**根目录**创建 `conftest.py` 文件(名称固定不可更改): ```python # 项目根目录/conftest.py import pytest @pytest.fixture(autouse=True, scope="session") def global_setup_teardown(): # 测试前执行(整个测试会话只执行一次) print("\n=== 全局初始化 ===") yield # 分隔 setup 和 teardown # 测试后执行(整个测试会话只执行一次) print("\n=== 全局清理 ===") ``` #### 2. 关键配置说明 - **`autouse=True`** 使 fixture 自动应用于所有测试用例,无需显式声明 - **`scope="session"`** 作用域设置为整个测试会话(可替换为 `"function"`/`"class"`/`"module"`) - **yield 机制** `yield` 前为 setup 逻辑,后为 teardown 清理逻辑 #### 3. 验证效果 创建测试文件: ```python # tests/test_demo.py def test_case1(): print("执行测试1") def test_case2(): print("执行测试2") ``` 执行输出: ``` === 全局初始化 === 执行测试1 . 执行测试2 . === 全局清理 === ``` #### 4. 作用域规则 1. **层级生效** fixture 对当前目录及所有子目录生效 2. **优先级原则** 子目录的 `conftest.py` 优先级高于父目录(就近生效) 3. **多文件共享** 无需 import,pytest 自动发现[^1][^2] #### 5. 应用场景 - 数据库连接池初始化/销毁 - 临时文件目录创建/清理 - 全局配置加载 - 许可证检查 - 测试环境验证[^3] > 注意:当同时存在多个 `autouse=True` 的 fixture 时,执行顺序按 **作用域从大到小**(session > module > class > function),同作用域按定义顺序执行。 --- ### 相关问题 1. **如何控制多个 `autouse` fixture 的执行顺序?** [参考:pytest 依赖管理机制] 2. **`session` 作用域和 `function` 作用域在资源消耗上有何区别?** [参考:fixture 作用域优化实践] 3. **子目录的 `conftest.py` 如何覆盖根目录的 fixture?** [参考:pytest 配置优先级机制] 4. **`yield` 和 `addfinalizer` 在 teardown 处理中有何优劣?** [参考:fixture 生命周期管理] [^1]: Pytest 中 `@pytest.fixture()` 装饰器和 `conftest.py` 配置文件的使用 [^2]: pytest 框架中 fixture 跨模块共享(`conftest.py`) [^3]: 深度解析 Pytest 中的 `conftest.py`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值