网络测试助手¶
概述¶
在 “@odoo/hoot” 模块之后,测试文件中第二个最需要的模块应该是 "@web/../tests/web_test_helpers"。
该模块包含将 Hoot 提供的低级帮助程序与 Odoo 测试中使用的所有最常见功能相结合的所有帮助程序。
这些帮助器有很多,文档的这一部分将仅重点介绍最常见的帮助器以及它们彼此交互的方式。
有关可用助手的完整列表,您可以参考 web_test_helpers file。
模拟环境¶
makeMockEnv 助手是可以生成 env 的最低助手。
它将照顾
创建
env对象本身,并预先配置了 Web 组件正常运行所需的所有属性,例如getTemplate或translateFn;生成
MockServer(如果该测试尚不存在);启动所有已注册的 services,并等待它们全部准备好;
启动与服务无关的其他功能,例如网络
router;保证在测试结束时拆除其设置中的所有功能。
此方法非常适合测试低级功能,例如未绑定到 Component 的 services:
// Can be further configured, but is already packed with all the necessary stuff
const env = await makeMockEnv();
expect(env.isSmall).toBe(false);
注解
与 makeMockServer 一样,对于给定测试只有一个 env 可以处于活动状态。无需手动调用 makeMockEnv 来检索当前环境实例;可以调用 getMockEnv 助手。
安装组件¶
通过使用 mountWithCleanup 帮助器,实例化 components 并将其附加到 DOM 应该很容易。它将在内部准备一个 env (如果尚不存在),这反过来又确保 MockServer 正在运行。
它采用 Component 类作为其第一个参数,以及*可选*参数的第二个参数,用于指定 props 或自定义 target:
await mountWithCleanup(Checkbox, {
props: {
value: false
},
});
该助手将返回活动的 Component 实例。
重要
检索 Component 实例以直接与其交互或对其内部变量执行断言通常是“不明智的”。唯一“接受”的用例是当 Component 在 DOM 中显示难以检索的信息时,例如 canvas 中的图形。对于大多数情况,最好在 DOM 中查询派生信息。
安装视图¶
安装视图只需将 mountWithCleanup 与 View 组件和正确的属性结合使用即可。
为此,Web 测试助手导出 mountView 助手,采用参数对象确定视图 type、resModel 和其他可选属性,例如 XML arch:
// Resolves when the view is fully ready
await mountView({
type: "list",
resModel: "res.partner",
arch: /* xml */ `
<list>
<field name="display_name" />
</list>
`,
});
与之前在 mountView 之上构建的帮助程序一样,它将确保 env 和 MockServer 都在当前测试中运行。
注解
与 mountWithCleanup 一样,*不*建议检索返回的 View 组件实例。然而,对于像 Graph view 这样的情况,这是可以完成的。
与组件交互¶
Hoot 提供了与 DOM 交互的帮助器(例如 click、press 等)。然而,这些助手在与更复杂的组件交互时存在两个问题:
帮助者尝试立即进行交互,而有时该元素尚未附加到文档(在未知的时间内);
每个调度事件的助手只等待一个微任务滴答,而大多数基于 Owl 的 UI 至少需要一个完整的动画帧来更新。
// Edit record name
await click(".o_field_widget[name=name]");
await edit("Gaston Lagaffe");
// Potential error 1: button may not be in the DOM yet
await click(".btn:contains(Save)");
// Potential error 2: view is not yet updated
expect(".o_field_widget[name=name]").toHaveText("Gaston Lagaffe");
考虑到这些限制,Web 测试助手提供了 contains 助手:
// Combines 'click' + 'edit' + 'animationFrame' calls
await contains(".o_field_widget[name=name]").edit("Gaston Lagaffe");
// Waits for (at least) a full animation frame after the click
await contains(".btn:contains(Save)").click();
expect(".o_field_widget[name=name]").toHaveText("Gaston Lagaffe");
这种方法虽然看起来离“单元测试”的概念有点远,但仍然是测试更复杂的单元(例如 views、WebClient 或 services 对和组件之间的交互)的一种很好且方便的方法。
然而,它不应该成为所有交互的默认设置,因为其中一些交互仍然需要在给定的时间范围内*精确地*发生,这是 contains 完全忽略的一个概念。
注解
Hoot 中的大多数助手都可用作 contains 实例的方法,具有(通常)相同的形状和 API。