--
:
--
:
--
第四阶段:Mock技术与代码覆盖率
最后更新于:
第四阶段:Mock技术与代码覆盖率
一、Mock技术
1.1 什么是Mock?
Mock是一种测试技术,用于隔离被测代码与外部依赖,使测试更加可靠和快速。
场景示例:
- 测试一个调用数据库的函数,不想真的连接数据库
- 测试一个调用外部API的函数,不想真的发送HTTP请求
- 测试一个调用时间相关函数的代码,想控制时间返回值
1.2 unittest.mock基础
Python标准库unittest.mock提供了Mock功能,pytest-mock插件使其使用更加方便。
1.3 Mock对象的基本用法
1from unittest.mock import Mock
2
3mock_obj = Mock()
4mock_obj.some_method.return_value = 42
5result = mock_obj.some_method()
6assert result == 421.4 Mock的常用方法和属性
| 方法/属性 | 说明 | 示例 |
|---|---|---|
return_value | 设置方法返回值 | mock.get.return_value = {"data": "test"} |
side_effect | 设置方法执行效果 | mock.get.side_effect = Exception("Network error") |
call_args | 获取调用参数 | mock.get.call_args == (("url",), {"timeout": 10}) |
called | 判断是否被调用 | assert mock.get.called |
call_count | 获取调用次数 | assert mock.get.call_count == 2 |
reset_mock() | 重置Mock状态 | mock.get.reset_mock() |
1.5 使用@pytest.mark.mocker
1def test_with_mocker(mocker):
2 mock_get = mocker.patch("requests.get")
3 mock_get.return_value.json.return_value = {"data": "test"}
4 # 测试代码1.6 使用@patch装饰器
1from unittest.mock import patch
2
3@patch("requests.get")
4def test_with_decorator(mock_get):
5 mock_get.return_value.json.return_value = {"data": "test"}
6 # 测试代码1.7 Mock类依赖
1def test_with_mocked_class():
2 mock_service = Mock()
3 mock_service.get_user.return_value = {"id": 1, "name": "Test"}
4
5 service = OrderService(mock_service)
6 result = service.create_order(1, items)
7 assert result["user_name"] == "Test"二、代码覆盖率
2.1 什么是代码覆盖率?
代码覆盖率是衡量测试用例覆盖源代码程度的指标,通常以百分比表示。
2.2 覆盖率类型
| 类型 | 说明 |
|---|---|
| Line Coverage | 行覆盖率:有多少行代码被执行 |
| Branch Coverage | 分支覆盖率:有多少条件分支被执行 |
| Function Coverage | 函数覆盖率:有多少函数被调用 |
| Statement Coverage | 语句覆盖率:有多少语句被执行 |
2.3 使用pytest-cov
1# 安装插件
2pip install pytest-cov
3
4# 统计代码覆盖率
5pytest --cov=src --cov-report=html
6
7# 查看未覆盖的代码行
8pytest --cov=src --cov-report=term-missing
9
10# 生成覆盖率报告
11pytest --cov=src --cov-report=html --cov-report=xml2.4 覆盖率配置
在pytest.ini中配置覆盖率:
1[pytest]
2addopts = --cov=src --cov-report=term-missing2.5 排除文件
1pytest --cov=src --cov-exclude="src/__init__.py" --cov-exclude="src/config.py"三、示例代码
3.1 Mock示例
1# tests/test_user_service.py
2import pytest
3from src.user_service import UserService
4
5def test_get_user_success(mocker):
6 mock_get = mocker.patch("requests.get")
7 mock_response = Mock()
8 mock_response.status_code = 200
9 mock_response.json.return_value = {"id": 1, "name": "Test User"}
10 mock_get.return_value = mock_response
11
12 service = UserService("https://api.example.com")
13 result = service.get_user(1)
14
15 assert result == {"id": 1, "name": "Test User"}
16 mock_get.assert_called_once_with("https://api.example.com/users/1")3.2 Mock类依赖示例
1# tests/test_order_service.py
2import pytest
3from unittest.mock import Mock
4from src.order_service import OrderService
5
6def test_create_order_success(mock_user_service):
7 mock_user_service.get_user.return_value = {"id": 1, "name": "Test User"}
8
9 service = OrderService(mock_user_service)
10 items = [{"name": "Item 1", "price": 100}]
11 order = service.create_order(1, items)
12
13 assert order["user_id"] == 1
14 assert order["user_name"] == "Test User"3.3 被测代码示例
1# src/user_service.py
2import requests
3
4class UserService:
5 def __init__(self, api_url):
6 self.api_url = api_url
7
8 def get_user(self, user_id):
9 response = requests.get(f"{self.api_url}/users/{user_id}")
10 if response.status_code == 200:
11 return response.json()
12 else:
13 return None
14
15 def create_user(self, user_data):
16 response = requests.post(f"{self.api_url}/users", json=user_data)
17 if response.status_code == 201:
18 return response.json()
19 else:
20 raise ValueError(f"Failed to create user: {response.status_code}")四、易错点与注意事项
4.1 Mock常见错误
- patch路径错误:patch的路径必须是被测代码中实际导入的路径
- Mock对象方法未调用:忘记调用被Mock的方法
- Mock返回值设置错误:设置了错误的返回值结构
- 忘记重置Mock:在多个测试中共享Mock对象时需要重置
4.2 覆盖率常见错误
- 覆盖率过高追求:100%覆盖率不是目标,代码质量才是
- 测试不充分:覆盖了代码但没有测试实际逻辑
- 排除过多:排除了重要的业务代码
- 忽略分支覆盖:只关注行覆盖,忽略条件分支
4.3 最佳实践
- Mock外部依赖,不Mock被测代码
- 使用
assert_called_once_with()验证调用参数 - 合理设置覆盖率目标(如80%以上)
- 定期检查覆盖率报告,补充缺失的测试
五、小结
本阶段学习了Mock技术和代码覆盖率,包括:
- unittest.mock的基本用法
- pytest-mock插件的使用
- Mock对象的常用属性和方法
- 代码覆盖率的统计和分析
- 覆盖率报告的生成
📡
👤
作者:
阿海
🌐
版权:
本站文章除特别声明外,均采用
CC BY-NC-SA 4.0
协议,转载请注明来自
阿海 Blog!
- 01JMeter界面详解 2026-07-11
- 02性能测试学习路线 2026-07-11
- 03JMeter线程组配置详解 2026-07-11