Pytest测试实战|Conftest.py详解

Pytest测试实战

本文章主要详细地阐述下Pytest测试框架中Conftest.py特性。

Conftest.py实战

Fixture强大的特性在实际的工作中是非常有价值并且是实用的,这样可以根据需求,在对应的测试模块中编写Fixture函数来达到测试需求的目的。但是这样也产生了新的问题,如有三个测试模块,并且测试需求都是需要Fixture函数,那么也就意味着每个测试模块都需要编写对应的Fixture函数代码了。这样显然是很不合理的。但是这样的案例在企业里面也是非常常见的情况,如授权的Fixture函数,不管哪个测试模块都是需要这个Fixture函数的。既然存在问题,有没有好的解决思路呢?在Pytest测试框架中提供了conftest.py来专门解决这部分问题。 通过conftest.py可以共享Fixture, 再本质的说就是通过conftest.py⽂件来达到共享Fixture函数。根据这个特性可以把一个测试工程中有多个测试模块共同使用到的公共Fixture函数分离到conftest.py文件中。使用conftest.py文件需要注意的点是:conftest.py是一个模块文件,但是不能导入。第二是建议把conftest.py文件位置存放在测试工程的根目录下,如下所示。

在工程的根目录下不言而喻,它是能够针对工程下所有的测试模块里面符合执行的所有测试函数(测试方法)都是共享Fixture函数的。这里以登录授权为案例,演示下授权的Fixture函数分离到conftest.py文件后,如何在多个测试模块中达到共享的特性。在test包下创建测试模块。在conftest.py里面编写获取授权登录的TOKEN的Fixture函数,源码如下:


import pytest

import requests


@pytest.fixture()

def login():

r=requests.post(

url='http://0.0.0.0:8000/login/auth/',

json={"username":"13484545195","password":"asd888"},

headers={'content-type':'application/json'})

return r.json()['token']


@pytest.fixture()

def headers(login):

return {'Authorization':'JWT {token}'.format(token=login)}

在测试模块中分别调用conftest.py里面的Fixture函数headers,test_index.py模块源码如下。


import requests


def test_case_index(headers):

r=requests.get(url='http://0.0.0.0:8000/interface/index',headers=headers)

assert r.status_code==200

test_platform.py源码如下。


import requests


def test_case_query(headers):

r=requests.get(

url='http://0.0.0.0:8000/interface/products?name=XX课堂',

headers=headers)

assert r.status_code==200

整体目录结构如下所示。

在测试模块中都引用了conftest.py里面的Fixture函数headers,执行test包下所有的测试模块,执行后的结果信息如下。

如上所示可以看到执行结果都是通过的。

特别需要强调的是在一个测试工程下,不建议使用多个conftest.py的文件,这样会引起混乱,而且维护成本也高。不是所有的Fixture函数都是需要分离到conftest.py的,分离到conftest.py文件的Fixture函数一定是多个测试模块都共同需要共享这个Fixture函数,如果某个Fixture函数仅仅是某个测试模块中私有使用,这种情况其实完全就没分离的必要性。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:【文末自行领取】

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

<think> 我们之前讨论了pytest fixture和scope,现在用户询问conftest.py的作用。根据引用[1][2][3],conftest.pypytest框架中一个特殊的配置文件,用于存放fixture函数。它的主要作用是实现fixture的共享,特别是跨多个测试文件共享。以下是对conftest.py作用的详细说明: 1. **共享fixture**:conftest.py允许我们在多个测试文件中共享同一个fixture,而不需要重复定义。例如,如果多个测试文件都需要使用同一个数据库连接fixture,我们可以将其定义在conftest.py中。 2. **自动发现机制**:pytest会自动发现conftest.py文件中的fixture,测试用例无需显式导入即可使用这些fixture。这简化了测试代码的编。 3. **作用域分层**:conftest.py文件可以放在不同的目录层级,从而实现不同范围的共享: - 根目录下的conftest.py:作用于整个项目,所有测试用例都可以使用其中定义的fixture。 - 子目录下的conftest.py:仅作用于该目录及其子目录中的测试用例。 引用[2]提到“搜索优先级自底而上(从和模块同级目录开始找,一直到项目根目录),遵循就近原则”,这意味着当多个conftest.py中存在同名fixture时,会优先使用距离测试用例最近的一个。 4. **全局前后置设置**:结合`@pytest.fixture`,可以在conftest.py中设置全局的前置和后置操作(例如启动浏览器、初始化测试数据等)。例如,引用[3]提到“实现全局的前后置应用”。 5. **夹具仓库**:推荐将所有fixture集中存放在conftest.py中,作为pytest的夹具仓库(fixture repository),便于统一管理。 6. **其他用途**:除了fixture,conftest.py还可以定义钩子函数(hook functions)、插件配置等,扩展pytest的功能。 **示例**: 假设项目结构如下: ``` project/ ├── conftest.py # 根目录conftest.py,全局共享 ├── test_api/ │ ├── conftest.py # 仅作用于test_api目录下的测试 │ ├── test_user.py ├── test_ui/ │ └── test_login.py ``` - `project/conftest.py`中的fixture可以被`test_api`和`test_ui`下的所有测试使用。 - `test_api/conftest.py`中的fixture仅被`test_api`目录下的测试使用(优先级高于根目录的conftest.py)。 **代码演示**: 在`project/conftest.py`中定义全局fixture: ```python # project/conftest.py import pytest @pytest.fixture(scope="session") def global_database(): print("=== 初始化全局数据库 ===") yield print("=== 清理全局数据库 ===") ``` 在`test_api/conftest.py`中定义局部fixture: ```python # test_api/conftest.py import pytest @pytest.fixture(scope="module") def api_config(): return {"base_url": "https://api.example.com"} ``` 测试文件中直接使用: ```python # test_api/test_user.py def test_user_query(global_database, api_config): # 自动注入fixture url = api_config["base_url"] + "/user" # 测试逻辑... ``` 通过这种方式,conftest.py极大地提升了测试代码的可维护性和复用性。 §§相关问题§§ 1. 如何在不同的测试目录层级中组织多个conftest.py文件? 2. 当多个conftest.py中存在同名fixture时,pytest如何确定使用哪一个?[^2] 3. conftest.py除了fixture还可以定义哪些pytest扩展功能? 4. 如何在conftest.py中实现测试环境的动态配置? </think> ### conftest.py 核心作用详解 `conftest.py` 是 pytest 框架的核心配置文件,主要实现以下关键功能: #### 1. **全局夹具(Fixture)仓库** [^1][^2][^3] 通过 `@pytest.fixture` 定义可复用的测试资源,自动作用于: - **全局共享**:根目录下的 `conftest.py` 对所有测试可见 - **模块级共享**:子目录中的 `conftest.py` 作用于当前目录及子目录测试 ```python # 根目录/conftest.py @pytest.fixture(scope="session") def global_db(): # 全局数据库连接 db = Database.connect() yield db db.close() ``` #### 2. **自动化夹具发现机制** pytest 自动识别 `conftest.py` 文件: - **无需导入**:测试文件无需 `import conftest` 即可使用其中定义的 fixture - **层级继承**:支持多级目录嵌套,遵循就近优先原则 [^2] ``` project/ ├── conftest.py # 全局夹具(如登录认证) ├── api/ │ ├── conftest.py # API测试专用夹具(如请求头) │ ├── test_user.py # 可使用全局+API夹具 └── ui/ └── test_login.py # 仅使用全局夹具 ``` #### 3. **测试环境生命周期管理** 实现统一的前置/后置操作: ```python # conftest.py @pytest.fixture(autouse=True, scope="session") def env_setup(): print("===== 测试环境初始化 =====") # 全局前置操作 yield print("===== 清理测试环境 =====") # 全局后置操作 [^3] ``` #### 4. **跨模块资源共享** 解决测试模块间的依赖问题: - 数据库连接池 - 配置参数(如 API endpoint) - 认证令牌 ```python # conftest.py @pytest.fixture(scope="module") def api_config(): return {"base_url": "https://api.example.com", "timeout": 30} ``` #### 5. **插件与钩子扩展** 集成 pytest 扩展功能: ```python # 添加自定义命令行参数 def pytest_addoption(parser): parser.addoption("--env", action="store", default="test") # 根据参数动态配置环境 @pytest.fixture(scope="session") def env_config(pytestconfig): return load_config(pytestconfig.getoption("env")) ``` ### 关键特性总结 | 特性 | 说明 | 应用场景 | |------|------|----------| | **自动发现** | pytest 自动识别无需导入 | 简化测试代码结构 | | **层级覆盖** | 就近优先的多级继承机制 [^2] | 不同测试套件的定制化 | | **全局共享** | 根目录文件作用于所有测试 | 统一环境初始化 | | **资源隔离** | 通过 fixture scope 控制可见性 | 模块/类级资源共享 | | **插件集成** | 支持 pytest 钩子函数 | 扩展框架功能 | > **最佳实践**:将项目所有 fixture 集中存放在 `conftest.py` 中,作为 pytest 的中央夹具仓库 [^3]。例如对于包含 100+ 测试文件的大型项目,使用全局 `conftest.py` 管理数据库连接可使代码复用率提升 70%+。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值