用途:为 Frappe v14+ 应用提供可维护测试的编写参考,重点覆盖测试规模增长后仍稳定的模式,包括工厂函数、fixture 隔离、mock 与导致 CI 偶发失败的反模式。
主要能力:
- 基类选择:涉及 Frappe 的控制器、API、数据库用 from frappe.tests.utils import FrappeTestCase,它提供每测试事务回滚、frappe.flags.in_test=True、从 test_records.json 加载测试记录、权限隔离;纯 Python 辅助函数才用 unittest.TestCase。
- 文件与命名:测试放在 <module>/doctype/<doctype>/test_*.py,非 DocType 测试放 my_app/tests/;测试方法以 test_ 开头,工厂与断言辅助方法用 _make_invoice、_assert_balanced 等命名。
- 数据生命周期:test_records.json 作为套件级 fixture,每次运行加载一次,以 ignore_permissions=True 创建;setUpClass 用于只读共享设置,setUp 用于会被修改的状态,多数测试无需 tearDown。
- 工厂模式:编写 make<thing>(**overrides) 辅助方法,默认值可被覆盖,仅按测试创建会变化的数据。
- 权限测试:用 frappe.set_user 切换用户,配合 assertRaises(frappe.PermissionError) 验证受限操作,结束后显式重置为 Administrator。
- Mock:使用标准库 unittest.mock.patch,可 mock frappe.sendmail、requests.post、frappe.publish_realtime,并检查调用参数。
- change_settings 上下文管理器:临时修改 Single doctype 设置,退出时自动恢复,即使测试失败。
- 后台任务:直接调用函数,或用 frappe.enqueue(..., now=True) 在当前进程同步执行。
- API 测试:白名单方法可直接导入调用,验证返回类型、权限边界;HTTP 层测试可参考 frappe.tests.test_api。
覆盖策略:应测试 validate 与生命周期钩子各分支、on_submit/on_cancel 副作用、白名单方法、自定义查询、复杂计算与权限边界;不应测试 Frappe 内部、生成的 CRUD、风格选择与实现细节。
限制与注意:不要在测试中调用 frappe.db.commit(),避免依赖测试执行顺序、硬编码用户邮箱、断言自动生成的名称、捕获泛型 Exception、使用 time.sleep;优先 mock 函数而非在生产代码中分支 frappe.flags.in_test。资料未提供具体安装命令、收费或平台信息。