如何为Django API集成测试测量代码覆盖率?
你遇到的核心问题是:使用requests.Session()调用Django API的测试中,后端user_data(你描述里的user_settings是笔误)函数的执行没有被coverage统计。原因在于测试进程和Django后端进程是相互独立的,默认情况下coverage只会追踪测试进程的代码执行,后端进程的运行完全脱离了coverage的监控范围,哪怕日志显示代码已执行,也不会出现在覆盖率报告里。
结合你使用的旧版本coverage==4.5.4和pytest-cov==2.10.1,以下是可落地的解决方案:
1. 改用pytest-django的live_server fixture管理后端进程
首先安装pytest-django(如果没装的话):
pip install pytest-django
修改测试代码,用live_server fixture获取后端的完整运行地址,确保后端进程由pytest统一管理:
def test_some_api(live_server): client = requests.Session() # 拼接live_server的完整URL发起请求 response = client.get(f"{live_server.url}/api/account/data") assert response.status_code == 200
2. 配置coverage跨进程追踪
coverage 4.x版本需要手动开启跨进程支持,让后端进程也生成覆盖率数据:
修改.coveragerc配置
在你的dir/.coveragerc中添加跨进程相关配置:
[run] parallel = True # 开启多进程模式,每个进程生成独立的覆盖率文件 source = dir # 保持你原来的源码路径配置 # 保留你已有的exclude规则
让Django后端进程启动时自动加载coverage
在项目的manage.py或者wsgi.py中添加以下代码(仅在测试环境生效):
import os import coverage # 只在测试且开启覆盖率统计时初始化 if os.environ.get('RUN_COVERAGE') == '1': cov = coverage.Coverage(config_file='dir/.coveragerc') cov.start()
3. 调整测试启动命令
启动测试时设置环境变量,触发后端进程的coverage初始化:
RUN_COVERAGE=1 pytest -v --cov-report html:html-report --cov=dir --cov-config=dir/.coveragerc
4. 合并多进程覆盖率数据
因为parallel = True会生成多个.coverage.*格式的文件,需要手动合并后再生成最终报告:
coverage combine coverage html -d html-report
你也可以把合并步骤写到conftest.py的fixture里,实现自动化:
import coverage import pytest @pytest.fixture(scope='session', autouse=True) def merge_coverage(): yield # 测试结束后合并所有进程的覆盖率数据 coverage.Coverage.combine() # 重新生成HTML报告 cov = coverage.Coverage(config_file='dir/.coveragerc') cov.load() cov.html_report(directory='html-report')
运行测试后打开html-report/index.html,查看dir/models/account/api.py的覆盖率数据,user_data函数内的if代码块应该会被标记为已执行。
内容的提问来源于stack exchange,提问作者Saidden

