如何在GitLab CI中使用pytest测试Django sqlite3数据库更新类
现有方案合理性评估
现有方案不符合pytest-django的最佳实践,存在3个明显错误,直接导致测试库无法自动生成表结构:
- 数据库配置中错误添加了
TEST.MIRROR参数:该参数的作用是让测试库直接复用指定生产库的连接,不会自动创建独立的临时测试库,也不会触发自动迁移逻辑,完全抵消了pytest-django的测试库自动管理能力 - CI流程冗余且不合规:提前执行的
makemigrations、migrate仅作用于配置中指定的生产库文件db.sqlite3,对pytest启动的测试库完全不生效;且makemigrations应该在本地开发阶段执行并将生成的迁移文件提交到代码仓库,不应该放在CI中自动执行,容易出现预期外的迁移差异 - 自动迁移逻辑被配置拦截:pytest-django默认会为带
@pytest.mark.django_db标记的用例自动创建临时测试库并执行全量迁移,你的当前配置直接禁用了该特性
正确实现步骤
- 首先修正Django数据库配置,删除
TEST.MIRROR配置项,sqlite3作为测试驱动时默认会自动创建内存级临时测试库,无需额外配置,修改后配置如下:
DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", "NAME": os.path.join(BASE_DIR, "db.sqlite3"), }, }
- 调整GitLab CI执行命令,移除提前的迁移操作,直接执行pytest即可,pytest-django会自动完成测试库创建、全量迁移的全流程:
# 提前确认依赖已安装,若原有CI流程已有依赖安装步骤可跳过 python3.9 -m pip install -r requirements.txt pytest -s -v --cov --cov-config .coveragerc -ra --tb=short {posargs:}
- 现有测试用例的
@pytest.mark.django_db标记无需修改,已经可以正常触发测试库权限校验和初始化逻辑。如果测试需要提前灌入基础测试数据,可以定义全局fixture复用:
import pytest from your_app.models import YourModel @pytest.fixture def base_test_data(django_db_setup, django_db_blocker): with django_db_blocker.unblock(): # 插入测试所需的基础数据 YourModel.objects.create(field1="xxx", field2="yyy") return YourModel.objects.all()
可选优化
本地开发测试时,可以在pytest命令后添加--reuse-db参数,复用之前生成的测试库,避免每次执行测试都重新跑全量迁移,大幅提升测试执行速度。
内容的提问来源于stack exchange,提问作者sqoshi
相关产品推荐
相关产品推荐

