pytest文档5-fixture之conftest.py

前言

前面一篇讲到用例加setup和teardown可以实现在测试用例之前或之后加入一些操作,但这种是整个脚本全局生效的,如果我想实现以下场景:
用例1需要先登录,用例2不需要登录,用例3需要先登录。很显然这就无法用setup和teardown来实现了。这就是本篇学习的目的,自定义测试用例的预置条件

fixture优势

1.firture相对于setup和teardown来说应该有以下几点优势

  • 命名方式灵活,不局限于setup和teardown这几个命名
  • conftest.py 配置里可以实现数据共享,不需要import就能自动找到一些配置
  • scope="module" 可以实现多个.py跨文件共享前置
  • scope="session" 以实现多个.py跨文件使用一个session来完成多个用例
fixture(scope="function", params=None, autouse=False, ids=None, name=None):
    """使用装饰器标记fixture的功能
     ** 作者:上海-悠悠 QQ交流群:588402570**
     可以使用此装饰器(带或不带参数)来定义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>')“”。

Fixtures可以选择使用yield语句为测试函数提供它们的值,而不是return。 在这种情况下,yield语句之后的代码块作为拆卸代码执行,而不管测试结果如何。fixture功能必须只产生一次

fixture参数传入(scope="function")

1.实现场景:用例1需要先登录,用例2不需要登录,用例3需要先登录

# 新建一个文件test_fixt.py
# coding:utf-8
** 作者:上海-悠悠 QQ交流群:588402570**
import pytest

# 不带参数时默认scope="function"
@pytest.fixture()
def login():
    print("输入账号,密码先登录")

def test_s1(login):
    print("用例1:登录之后其它动作111")

def test_s2():  # 不传login
    print("用例2:不需要登录,操作222")

def test_s3(login):
    print("用例3:登录之后其它动作333")

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

运行结果:

============================= test session starts =============================
platform win32 -- Python 3.6.0, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: E:\YOYO, inifile:
collected 3 items

test_fix.py 输入账号,密码先登录
用例1:登录之后其它动作111
.用例2:不需要登录,操作222
.输入账号,密码先登录
用例3:登录之后其它动作333
.

========================== 3 passed in 0.06 seconds ===========================

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

conftest.py配置

1.上面一个案例是在同一个.py文件中,多个用例调用一个登陆功能,如果有多个.py的文件都需要调用这个登陆功能的话,那就不能把登陆写到用例里面去了。
此时应该要有一个配置文件,单独管理一些预置的操作场景,pytest里面默认读取conftest.py里面的配置

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

  • conftest.py配置脚本名称是固定的,不能改名称
  • conftest.py与运行的用例要在同一个pakage下,并且有__init__.py文件
  • 不需要import导入 conftest.py,pytest用例会自动查找

2.参考脚本代码设计如下

** 作者:上海-悠悠 QQ交流群:588402570**
__init__.py

conftest.py
    # coding:utf-8
    import pytest

    @pytest.fixture()
    def login():
        print("输入账号,密码先登录")

test_fix1.py
    # coding:utf-8
    import pytest
    
    def test_s1(login):
        print("用例1:登录之后其它动作111")
    
    def test_s2():  # 不传login
        print("用例2:不需要登录,操作222")
    
    def test_s3(login):
        print("用例3:登录之后其它动作333")
    
    if __name__ == "__main__":
        pytest.main(["-s", "test_fix1.py"])

test_fix2.py
    # coding:utf-8
    import pytest
    
    def test_s4(login):
        print("用例4:登录之后其它动作111")
    
    def test_s5():  # 不传login
        print("用例5:不需要登录,操作222")
    
    if __name__ == "__main__":
        pytest.main(["-s", "test_fix2.py"])

3.单独运行test_fix1.py和test_fix2.py都能调用到login()方法,这样就能实现一些公共的操作可以单独拿出来了
---------------------------------pytest结合selenium自动化完整版-------------------------

全书购买地址 https://yuedu.baidu.com/ebook/902224ab27fff705cc1755270722192e4536582b

作者:上海-悠悠 QQ交流群:874033608

也可以关注下我的个人公众号:yoyoketang

1070438-20181009214319480-1673365725.jpg

1070438-20181009214319480-1673365725.jpg

<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、付费专栏及课程。

余额充值