【工程实战】第六篇:Mock 技术 —— 解决外部依赖的“拦路虎”:真戏假做的艺术
2026/4/17 19:48:21 网站建设 项目流程

专栏进度:06 / 10 (自动化实战专题)
Mock 的本质是模拟。它通过拦截真实的请求并返回预设的伪造数据,从而断开系统与不稳定依赖(如银行接口、高成本云服务、未完成的微服务)的连接。

一、 Mock 的两大阵地:单体测试 vs 集成测试

  1. 代码级 Mock(针对单元测试)
    在 Python 中,我们使用内置的 unittest.mock 或 pytest-mock 插件。它直接拦截代码中的函数调用。

应用场景:某个函数需要读取磁盘 1GB 文件,我们 Mock 它,直接让它返回一段文本。

  1. 协议级 Mock(针对接口/UI 自动化)
    通过拦截 HTTP 协议来实现。

应用场景:Playwright 拦截浏览器发出的 XHR 请求,或者使用 Mock Server(如 Moco, WireMock)作为代理。

二、 实战 1:使用 pytest-mock 拦截内部函数

安装插件:pip install pytest-mock

假设我们有一个发邮件的业务逻辑,我们不想每次测试都真发邮件:

Python

# business.pydefsend_email(address):# 这是一个耗时且依赖网络的操作print(f"正在给{address}发送真实邮件...")returnTruedefregister_user(user):# 注册逻辑...ifsend_email(user['email']):return"Register Success"

Python

# tests/test_mock.pydeftest_register_with_mock(mocker):# 使用 mocker.patch 拦截 send_email 函数mock_send=mocker.patch("business.send_email",return_value=True)user={"name":"Gemini","email":"test@example.com"}result=register_user(user)assertresult=="Register Success"# 验证该函数是否被正确调用过mock_send.assert_called_once_with("test@example.com")

三、 实战 2:Playwright 拦截接口(UI 自动化黑科技)

这是 Playwright 吊打 Selenium 的核心功能之一。它可以让浏览器“产生幻觉”。

Python

deftest_mock_api(page):# 拦截特定的 API 请求并返回 Mock 结果page.route("**/api/user/balance",lambdaroute:route.fulfill(status=200,body='{"balance": 9999999.99}',content_type="application/json"))page.goto("https://my-bank.com/profile")# 此时页面显示的余额将直接变为 9999999.99,而无需真的充值assertpage.locator("#balance_val").has_text("9999999.99")

四、 什么时候该用 Mock?什么时候不该用?

建议使用 Mock 严禁滥用 Mock
第三方支付、短信网关(收费且不稳定) 被测系统的核心业务逻辑(Mock 了就没测到本质)
后端接口尚未开发完成(前后端并行测试) 涉及到数据库一致性的最终检查
构造极端故障(如:超时、403、502) 已经处于生产环境上线前的最后验收测试

五、 避坑指南:Mock 的“反噬”

Mock 幻觉:如果 Mock 的数据结构与真实接口脱节,你的自动化测试虽然全是绿色(PASS),但上线后会直接崩溃。对策:定期进行“契约测试(Contract Testing)”,确保 Mock 数据与真实接口定义同步。

过度隔离:如果一个用例里 80% 的步骤都是 Mock 的,那么这个测试的真实性将大打折扣。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询