关于 sap-fiori-opa5-test-development
为 SAP Fiori Elements 应用编写、修复和扩展 OPA5 集成测试的开发技能,涵盖 OData V2 与 V4,并按版本指导选择测试库。
主要功能
- 01识别 OData V2 或 V4
- 02提供版本对应的测试库指南
- 03指导创建和注册测试 Journey
- 04说明测试运行与模拟服务器
- 05列出断言、清理和调试注意事项
适用场景
- 01为 Fiori Elements 应用新增集成测试 Journey
- 02排查 OPA5 测试失败或无效断言
- 03根据 OData 版本选择测试 API
- 04配置模拟数据并运行测试
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sap/ open-ux-tools --skill sap-fiori-opa5-test-development安装后在 Claude Code 中输入/sap-fiori-opa5-test-development确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/fiori-elements-v2-test-library.mdv2-instructions.mdv4-custom-selectors.mdv4-instructions.mdv4-journeyrunner.mdv4-sap-fe-test-api-guide.mdv4-standard-patterns.md详细介绍
SAP Fiori OPA5 开发技能
编写、修复和扩展 SAP Fiori Elements 应用 OPA5 集成测试的指南。
涵盖 OData V4(sap.fe.test)和 OData V2(fioriElementsTestLibrary)。
不适用于 freestyle UI5 应用——对于此类应用,建议使用 UI5 Plugins for Coding Agents ui5 中的 ui5-best-practices-opa5 技能。
前提条件
此技能要求已有一个由 SAP Fiori tools 生成的 SAP Fiori Elements 应用,并且其中包含测试文件夹(例如 webapp/test)。如果缺少该文件夹,请先检测 OData 版本,然后按照对应版本的指南操作。
步骤 1:定位项目根目录
当用户提供的是项目名称或 ID(例如 fin.test.rap.lr3),而不是文件路径时:
- 在常见项目根目录下搜索
manifest.json文件(例如webapp/manifest.json)。 - 将
sap.app中的"id"字段与给定名称匹配,或查找名称中包含给定 ID 的文件夹。 - 找到后,将包含
webapp/manifest.json的文件夹视为项目根目录,供后续所有步骤使用。
步骤 2:检测 OData 版本
编写任何测试代码之前,先确定应用使用的是 OData V4 还是 V2。这两个测试库完全不同,绝不能混用。
首选检查:manifest.json
| 检查结果 | 版本 | 测试库 |
|---|---|---|
sap.ui5.dependencies.libs 中包含 "sap.fe.templates" 键 | V4 | sap.fe.test |
"sap.ui.generic.app" 是根键 | V2 | fioriElementsTestLibrary |
备用检查:metadata.xml
如果无法从 manifest.json 得出结论,请检查服务元数据文件中的 <edmx:Edmx> 根元素(通常位于 webapp/localService/mainService/metadata.xml,或 ui5-mock.yaml 中 metadataPath 指向的位置):
| 属性值 | 版本 |
|---|---|
xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" 或 Version="4.0" | V4 |
xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" 或 Version="1.0" | V2 |
这些属性位于文件的第 1 行或第 2 行。
如果两种依据都无法确认版本,请在继续之前询问用户确认 OData 版本。
步骤 3:遵循对应指南
确认版本后:
- 阅读下方的共享章节(“测试端点和运行测试”以及“模拟服务器”),这些内容适用于 V4 和 V2。
- 然后阅读对应版本的指南,了解所有测试库相关决策:
- OData V4——阅读
references/v4-instructions.md - OData V2——阅读
references/v2-instructions.md
- OData V4——阅读
添加新 Journey
当用户要求添加一个额外的 Journey(而非仅在现有 Journey 中新增一个 opaTest)时:
- 查找测试根目录——在项目中搜索匹配
*Journey.js、*Journey.ts、*Journey.gen.js或*Journey.gen.ts的文件。这些文件所在的文件夹即为集成测试根目录。它们通常位于测试目录下名为integration的文件夹中,例如webapp/test/integration。 - 了解接线方式——阅读现有 Journey 文件和任何入口文件,了解 Journey 的注册方式。可能有以下三种配置:
- 虚拟端点(V4)——无需注册;中间件会自动识别所有匹配配置模式的文件(默认:以
Journey.js或Journey.ts结尾) - 物理入口点(V4)——将新 Journey 的模块路径添加到
OpaTests.qunit.js中的sap.ui.require数组 - 自定义接线(例如使用
AllJourneys.js或AllJourneys.json的 S/4 应用)——遵循现有模式
- 虚拟端点(V4)——无需注册;中间件会自动识别所有匹配配置模式的文件(默认:以
- 创建 Journey 文件,遵循现有 Journey 的命名模式。
- 向用户确认创建了哪个文件,以及它的注册方式(或说明注册是自动完成的)。
通用反模式(V4 和 V2)
无论使用哪个 OData 版本或测试库,这些规则都适用。
切勿臆造方法名称。 只能使用已确认存在于测试库中的方法。 如果快速参考模式中未展示某个方法,切勿猜测或拼凑名称——应先查证:
- V4:查看
references/v4-standard-patterns.md,了解常见模式。如果其中没有该方法,则查看references/v4-custom-selectors.md,了解自定义选择器模式。如果仍未找到,请阅读references/v4-sap-fe-test-api-guide.md,并查阅其中指向的官方sap.fe.testAPI 文档。方法“听起来合理”并不足够——必须确认它确实存在。 - V2:查看
references/fiori-elements-v2-test-library.md,其中包含所有 V2 页面对象的完整 API 参考。
臆造的方法会静默失败,并产生难以诊断的“not a function”运行时错误。
每个 opaTest 都必须至少包含一个 Then 断言。 只有 Given/When 步骤的测试会报告 0 个断言,并静默失败。
// ❌ No Then = no assertions, test fails
opaTest("Click button", function(Given, When, Then) {
When.onThePage.iClickButton();
});
// ✅ Always end with at least one Then
opaTest("Click button", function(Given, When, Then) {
When.onThePage.iClickButton();
Then.onThePage.iSeeThisPage();
});
OData 属性名称区分大小写——务必与 metadata.xml 中的大小写完全一致。大小写错误会导致超时,而不会显示错误消息。
在同一个 journey 中,OPA5 状态会在各个 opaTest 块之间延续。 测试按顺序运行并共享同一个浏览器会话——不要假设每个 opaTest 开始时应用都处于干净状态。务必显式导航并断言,而不要依赖前一个测试块留下的状态。
JourneyRunner(V4)中的 pages 映射键必须与 journey 中使用的访问器名称完全一致。 不匹配会导致静默运行时错误——journey 尝试调用页面对象时,该对象会是 undefined。(V2 通过模块加载全局注册页面对象,不使用 pages 映射。)
// ❌ Wrong - key is "onTheList" but journey calls "onTheListReport"
pages: { onTheList: ListReportPage }
// journey: When.onTheListReport.onTable()... → undefined
// ✅ Fixed - key matches accessor name exactly
pages: { onTheListReport: ListReportPage }
让 journey 保持精简——在约 10 个 opaTest 块处分拆。 大型 journey 文件难以调试且难以维护。每个功能或用户流程对应一个 journey 文件,是很好的经验法则。不要为测试库本身已覆盖的标准 Fiori Elements 行为添加测试。
Teardown 方法名称因版本而异。 务必在 Given 上调用 teardown,切勿在页面对象上调用:
- V4:
Given.iTearDownMyApp()(大写 D——在sap.fe.test.BaseArrangements中被覆盖) - V2:
Given.iTeardownMyApp()(小写 d——基础Opa5方法)
QUnit 需要断言来验证测试。Teardown 不是断言——务必在 teardown 前断言一些内容。
❌ 错误——此前没有断言就执行 teardown:
// V4
opaTest("Should clean up", function(Given, When, Then) {
Given.iTearDownMyApp();
});
// V2
opaTest("Should clean up", function(Given, When, Then) {
Given.iTeardownMyApp();
});
❌ 错误——在页面对象上链式调用 teardown,而不是在 Given 上调用:
// V4
opaTest("Should assert state and clean up", function(Given, When, Then) {
Then.onTheListPage.iSeeThisPage()
.and.onTheListPage.iTearDownMyApp();
});
✅ 正确:
// V4
opaTest("Should assert state and clean up", function(Given, When, Then) {
Then.onTheListPage.iSeeThisPage(); // assertion first
Given.iTearDownMyApp(); // teardown on Given, separate step
});
// V2
opaTest("Should assert state and clean up", function(Given, When, Then) {
Then.onTheGenericListReport.theResultListIsVisible(); // assertion first
Given.iTeardownMyApp(); // teardown on Given, separate step
});
测试端点和运行测试
以下内容适用于 V4 和 V2 项目。
虚拟测试端点(fiori-tools-preview 或 preview-middleware)
当 @sap/ux-ui5-tooling 或 @sap-ux/preview-middleware 在 ui5.yaml 或 ui5-mock.yaml 中配置了 test 块时,HTML 和 JS 入口文件会动态生成——磁盘上不需要存在实体 opaTests.qunit.html 或 OpaTests.qunit.js。
ui5-mock.yaml 配置示例:
server:
customMiddleware:
- name: fiori-tools-preview
configuration:
test:
- framework: OPA5
path: /test/opaTests.qunit.html # default, omit if unchanged
init: /test/opaTests.qunit.js # default, omit if unchanged
pattern: /test/**/*Journey{,.gen}.{js,ts} # default, omit if unchanged
如果配置路径下已存在实体文件,中间件会改为提供该文件(并显示警告)。使用虚拟端点的项目中,不要手动创建 opaTests.qunit.html 或 OpaTests.qunit.js——只要文件名符合配置的模式,新的 journey 文件就会自动被识别。
实体文件(经典设置)
如果没有虚拟端点,完整结构会存在于磁盘上:
webapp/test/integration/
├── opaTests.qunit.html <- test suite entry point (opened in browser)
├── OpaTests.qunit.js <- imports journeys and calls QUnit.start()
├── FirstJourney.js
└── pages/
└── ...
注册新 journey 时,需要将其模块路径添加到 OpaTests.qunit.js 中的 sap.ui.require 数组。
运行测试
通过 npm 脚本:
npm run int-test
查看 package.json 以确认准确的脚本名称。这会运行 fiori run --config ./ui5-mock.yaml --open 'test/integration/opaTests.qunit.html'。
手动运行(基于 CAP 的应用):
npm start # or: cds watch
然后在浏览器中打开:http://localhost:<port>/<app-name>/webapp/test/integration/opaTests.qunit.html
模拟服务
以下内容适用于 V4 和 V2 项目。
@sap-ux/ui5-middleware-fe-mockserver(推荐)
在 UI5 工具层运行,无需后端进程,因此是 OPA5 测试的推荐选择。支持 V4 和 V2 应用。
设置方法:
npx --yes @sap-ux/create@latest add mockserver-config
有两种数据模式——请根据测试断言的内容选择:
| 模式 | 配置 | 适用情况 |
|---|---|---|
| 静态模拟数据 | generateMockData: false | 测试断言具体值(精确数量、字段内容、ID)。JSON 文件位于 mockdataPath(默认值:./webapp/localService/mainService/data/)。每次运行的结果都一致。 |
| 动态模拟数据 | generateMockData: true | 测试只断言结构(字段可见、表格有行)。无需维护 JSON 文件,但无法断言精确值。 |
如果某个测试流程删除了记录(例如,通过
iExecuteDelete()),请在重新运行前重启服务以恢复数据。
sap.ui.core.util.MockServer(较旧的 V2 应用)
由较早工具生成的较旧 V2 应用可能会使用 UI5 框架内置的模拟服务。它通过 localService/mockserver.js 配置,并在浏览器中而非工具层运行。请参阅 UI5 文档:https://ui5.sap.com/#/topic/3a9728ec31f94ca18a7d543ce419d85d
CAP 后端
对于基于 CAP 的项目,cds watch / npm start 可用作数据后端。请将其留给需要测试 CAP 逻辑的专用集成测试或端到端测试套件;OPA5 测试优先使用模拟服务。
调试失败的测试
以下内容适用于 V4 和 V2 项目。
测试失败时,启用失败时暂停,以便应用在浏览器中保持运行,并停留在失败位置供你直接检查。在测试入口点中、运行器或任何 Opa5.extendConfig 调用之前添加此行:
sap.ui.test.qunitPause.pauseRule = "assert,timeout";
测试暂停后,在浏览器中检查正在运行的应用,查看 UI 实际显示的内容与测试预期是否一致。所有测试流程通过后,请删除此行。
对于 UI5 1.147 及更高版本,可以暂时将 TestRecorder 工具(sap.ui.testrecorder 库)添加到应用中,以检查实时控件树,并为非简单选择器生成可靠的 OPA5 代码片段。完成后请移除此库。
CI 上的测试不稳定——默认的 OPA5 超时时间(15s)对于 CI 环境通常太短。请在运行器配置中将其增加到 60(V4 使用 opaConfig.timeout,V2 使用 Opa5.extendConfig({ timeout: 60 }))。
参考文件
| 文件 | 何时阅读 |
|---|---|
references/v4-instructions.md | V4 应用:测试结构、JourneyRunner、页面对象、反模式、调试,以及按 UI 区域分类的模式和修复方法 |
references/v4-journeyrunner.md | V4:完整的 JourneyRunner 配置参考、磁贴名称查找、可移植的测试流程模式 |
references/v4-sap-fe-test-api-guide.md | V4:如何查阅 sap.fe.test API 文档、命名约定、标识符模式 |
references/v4-standard-patterns.md | V4:按 UI 区域分类的快速参考示例目录(应用启动、FilterBar、表格、标题、表单、页脚、对话框、区段、值帮助、图表、Shell) |
references/v4-custom-selectors.md | V4:自定义选择器(最后手段)、OpaBuilder、CustomFilterField ID、ComboBox、后缀陷阱 |
references/v2-instructions.md | V2 应用:设置、页面对象、V2 注意事项 |
references/fiori-elements-v2-test-library.md | V2:List Report、Object Page、ALP 和 FCL 页面对象的完整 API 参考——方法签名、常见陷阱、完整示例 |