目录

一、 环境准备

二、项目结构

三、项目代码示例

四、测试代码示例

五、Coverage配置

六、运行测试并收集覆盖率​​​​​​​

七、 覆盖率报告示例

八、关键点解析

九、常见问题


在我们进行接口测试前需要安装pytest和coverage,可能还需要pytest-cov插件,因为pytest-cov可以更方便地与pytest集成。不过,Coverage.py本身也可以单独使用,但用pytest-cov会更方便。

具体的操作步骤可以参考以下方案。

一、 环境准备

# 安装依赖pip install pytest coverage pytest-cov

二、项目结构​​​​​​​

my_project/├── src/                    # 项目代码│   └── api/│       ├── __init__.py│       └── user_service.py├── tests/                  # 测试代码│   ├── __init__.py│   └── test_user_api.py├── .coveragerc             # Coverage配置└── requirements.txt

三、项目代码示例

src/api/user_service.py:

python​​​​​​​

class UserService:    def __init__(self, db):        self.db = db    def get_user(self, user_id: int) -> dict:        """接口:根据ID获取用户"""        user = self.db.query("SELECT * FROM users WHERE id = ?", (user_id,))        if not user:            raise ValueError("User not found")        return {"id": user[0], "name": user[1]}    def create_user(self, name: str) -> int:        """接口:创建用户"""        if not name:            raise ValueError("Name cannot be empty")        user_id = self.db.execute("INSERT INTO users (name) VALUES (?)", (name,))        return user_id

四、测试代码示例

tests/test_user_api.py:

python​​​​​​​

from unittest.mock import Mockimport pytestfrom src.api.user_service import UserServiceclass TestUserService:    @pytest.fixture    def mock_db(self):        return Mock()    def test_get_user_success(self, mock_db):        # 模拟数据库返回        mock_db.query.return_value = (1, "Alice")        service = UserService(mock_db)        # 调用接口        user = service.get_user(1)        # 断言结果和行为        assert user == {"id": 1, "name": "Alice"}        mock_db.query.assert_called_with("SELECT * FROM users WHERE id = ?", (1,))    def test_get_user_not_found(self, mock_db):        mock_db.query.return_value = None        service = UserService(mock_db)        # 验证异常        with pytest.raises(ValueError):            service.get_user(999)    def test_create_user(self, mock_db):        mock_db.execute.return_value = 2        service = UserService(mock_db)        user_id = service.create_user("Bob")        assert user_id == 2        mock_db.execute.assert_called_with("INSERT INTO users (name) VALUES (?)", ("Bob",))

五、Coverage配置

.coveragerc:

ini​​​​​​​

[run]source = src/       # 仅统计项目代码(排除测试代码)omit = */__init__.py  # 忽略指定文件[report]show_missing = true  # 显示未覆盖的行skip_covered = true  # 隐藏已覆盖的文件fail_under = 80      # 覆盖率低于80%时报错

六、运行测试并收集覆盖率​​​​​​​

# 方式1:直接使用pytest-cov插件pytest --cov=src --cov-report=term --cov-report=html:cov_html# 方式2:分步执行(使用Coverage命令)coverage run -m pytest tests/coverage reportcoverage html

参数说明:

--cov=src:指定要统计覆盖率的代码目录

--cov-report=term:在终端显示简洁报告

--cov-report=html:cov_html:生成HTML报告到cov_html目录

--cov-fail-under=80:覆盖率低于阈值时测试失败

七、 覆盖率报告示例

终端输出:

text

图片

八、关键点解析

覆盖范围控制:

通过.coveragerc配置聚焦项目代码,排除测试代码。

使用omit过滤无需统计的文件(如初始化文件)。

Mock隔离依赖:

使用unittest.mock模拟数据库,避免真实依赖对覆盖率的影响。

异常路径覆盖:

测试中覆盖了raise ValueError的分支,确保异常逻辑被统计。

报告生成:

HTML报告可直观定位未覆盖的代码行(通过show_missing)。

九、常见问题

Q1:为什么覆盖率报告中某些行未统计?

A1:检查.coveragerc中的source和omit配置,确保目标文件在统计范围内。

Q2:如何仅统计接口测试覆盖率?

A2:通过标记区分测试类型:

pytest -m "interface" --cov=src

Q3:如何忽略某些代码块?

A3:在代码中添加注释:

python​​​​​​​

# pragma: no coverdef internal_helper():  # 此函数不计入覆盖率    pass
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐