使用pytest和mongoengine测试时数据写入主库而非测试库如何解决
问题:pytest运行时数据写入主数据库而非测试库
我已安装以下包:
python -m pip install pytest pytest-django
并创建了一个fixture:
# core/services/tests/fixtures/checkout.py import pytest from bson import ObjectId from datetime import datetime from core.models.src.checkout import Checkout @pytest.fixture(scope="session") def checkout(mongo_db): checkout = Checkout( user_id=59, amount=35_641, ) checkout.save() return checkout
将其导入到同目录的conftest.py中:
# core/service/tests/conftest.py from core.service.tests.fixtures.checkout import *
以下是我连接测试数据库的方式:
# conftest.py import pytest from mongoengine import connect, disconnect, connection @pytest.fixture(scope="session", autouse=True) def mongo_db(): connect( db="db", name="testdb", alias="test_db", host="mongodb://localhost:27017/", serverSelectionTimeoutMS=5000, ) connection._connections.clear() yield disconnect()
这是我的测试代码:
import json import pytest from core.service.checkout import a_function def test_a_function(checkout): assert checkout.value is False response = a_function(id=checkout.id, value=True) assert response.status_code == 200 response_data = json.loads(response.content.decode("UTF-8")) assert response_data.get("success", None) is True checkout.reload() assert checkout.value is True
但每次运行pytest时,都会在主数据库中创建新记录。请问如何修改才能使用测试数据库?
问题根源及修复方案
1. 删除错误的连接清空代码
你的mongo_db fixture里调用了connection._connections.clear(),这会直接清空刚建立的测试数据库连接,导致后续操作默认使用主库连接。必须删除这行代码。
2. 给模型指定测试数据库别名
Checkout模型需要明确绑定测试库的别名,否则会默认使用主库。修改模型文件(core/models/src/checkout.py):
from mongoengine import Document, fields class Checkout(Document): user_id = fields.IntField() amount = fields.IntField() value = fields.BooleanField(default=False) # 添加这行,绑定测试库别名 meta = { 'db_alias': 'test_db' }
如果模型已有meta配置,直接追加'db_alias': 'test_db'即可。
3. 修正数据库连接参数
connect函数中的db和name参数重复,调整参数明确指定测试库名称:
@pytest.fixture(scope="session", autouse=True) def mongo_db(): # 直接指定测试库名称为testdb,绑定别名test_db conn = connect( db="testdb", alias="test_db", host="mongodb://localhost:27017/", serverSelectionTimeoutMS=5000, ) yield conn # 断开时明确指定测试库别名 disconnect(alias="test_db")
4. 确保fixture操作使用测试库
在checkout fixture中,显式指定保存到测试库(如果模型已配置db_alias,此步骤可省略,显式指定更保险):
@pytest.fixture(scope="session") def checkout(mongo_db): checkout = Checkout( user_id=59, amount=35_641, ) checkout.save(alias="test_db") return checkout
5. 检查业务函数的数据库操作
确保a_function内部操作Checkout时指定测试库别名,比如:
# core/service/checkout.py中的a_function示例 def a_function(id, value): # 查询时指定别名 checkout = Checkout.objects(alias="test_db").get(id=id) checkout.value = value checkout.save(alias="test_db") # 其他业务逻辑...
完成以上修改后,运行pytest时数据就会写入testdb测试数据库,而非主库。
内容的提问来源于stack exchange,提问作者Amir Shabani
相关产品推荐
相关产品推荐

