ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

HarmonyOS 7 + Node.js-JSON Schema:审核测试路径与版本事实的一致性门禁【鸿蒙心迹】

HarmonyOS 7 + Node.js-JSON Schema:审核测试路径与版本事实的一致性门禁【鸿蒙心迹】 提交审核前团队通常会检查 HAP、截图、隐私声明和权限配置却容易把“审核说明”当成一段最后手写的文字。版本号已经升到 3.6.0说明里还写着 3.5.2功能入口从首页移到发票中心步骤仍让审核人员点击旧按钮测试账号已经轮换文档里却保留过期别名。每一项都不复杂组合起来却会让可用功能表现得像无法访问。本文构造ReviewPathGate小工具把审核说明改造成可验证的事实清单。任务为REVIEW-PATH-0069应用包名com.example.ledger版本3.6.0 (30600)目标功能invoice_import入口/pages/InvoiceImportPage测试账号别名reviewer_primary操作步骤 4 条。演示从 4 个发现项收敛到 0状态为MANIFEST_LOADED → FACTS_COLLECTED → ROUTES_PROBED → MATERIAL_MATCHED → PASS。所有账号和数据均为虚构示例不包含真实凭据也不宣称经历过真实审核失败。一、审核说明最大的问题是无法被程序理解一段自然语言可能写得很清楚但构建系统不知道里面的版本号是否过期也不知道“点击发票导入”在当前页面是否真的存在。只要发布节奏紧审核说明就会从上一版本复制过来再由不同同事分别修改截图、账号和步骤。最终每个文件看起来都合理组合后却描述了三套应用。ReviewPathGate 不尝试自动代写审核材料也不判断内容合规。它只验证团队能够确定的工程事实候选包的 bundleName、versionName、versionCode运行时导出的可审核路由功能标识与步骤数量测试账号是否使用已登记别名截图清单是否指向同一版本。至于审核规则、资质和内容判断仍以当前官方要求和人工复核为准。这种边界很重要。脚本通过不等于应用必然通过审核脚本失败却意味着材料内部已经自相矛盾不适合继续提交。门禁的价值是减少低级事实错误不是替代审核人员。二、把审核路径变成一份机器可读清单工具的入口是review-manifest.json。它不保存密码只保存凭据别名真正的测试密码放在受控密钥系统中由提交人员按流程填写。清单也不包含用户真实数据示例数据集使用固定虚构发票号。清单字段分四类应用事实、功能入口、测试身份、材料引用。每个 feature 都有稳定 ID页面改名时更新 route步骤只引用 actionId。图片文件不写绝对路径避免换机器后失效。版本字段必须同时写 name 和 code不能只凭展示字符串判断新旧。这段代码解决什么问题把分散在聊天和文档里的审核路径收敛为结构化清单为后续自动比对提供唯一输入。{$schema:./review-manifest.schema.json,taskId:REVIEW-PATH-0069,bundleName:com.example.ledger,versionName:3.6.0,versionCode:30600,accountAlias:reviewer_primary,features:[{id:invoice_import,route:/pages/InvoiceImportPage,steps:[open_invoice_center,tap_import,select_demo_file,confirm_preview],screenshots:[invoice_import_01.png,invoice_import_02.png]}]}清单读入后状态进入MANIFEST_LOADED。这里最容易犯的错误是把密码也写进 JSON 并提交仓库。别名只表示“发布流程中需要哪一组测试身份”不提供秘密本身。CI 只能检查别名是否在允许列表中不能打印密钥值更不能把凭据打进 HAP。JSON Schema 负责类型、必填字段、枚举和格式校验。例如 versionCode 必须是正整数route 必须以/pages/开头steps 至少一条且不重复。Schema 只能证明结构合法不能证明 route 存在因此后面还要采集工程事实。三、路由事实应由应用导出而不是脚本扫描源码猜测直接用正则搜索.ets文件不可靠。页面可能通过常量注册路由也可能由模块组合注释和测试样例还会产生假阳性。ReviewPathGate 在应用侧维护一份审核功能注册表运行页面和构建脚本都消费同一份静态数据。注册表不等于导航实现。它只暴露审核所需的 route、入口动作和最小前置条件不包含页面实例或 UIContext。这样 Node.js 脚本可以读取导出的 JSONArkTS 页面也能在内部诊断页展示同一结果。这段代码解决什么问题建立由应用代码维护的审核功能注册表避免构建脚本通过脆弱的源码正则推断页面是否存在。exportinterfaceReviewableFeature{id:stringroute:stringactions:string[]requiresAccount:boolean}exportconstREVIEWABLE_FEATURES:ReviewableFeature[][{id:invoice_import,route:/pages/InvoiceImportPage,actions:[open_invoice_center,tap_import,select_demo_file,confirm_preview],requiresAccount:true}]exportfunctionfindReviewFeature(id:string):ReviewableFeature|undefined{returnREVIEWABLE_FEATURES.find(itemitem.idid)}注册表必须与真实导航入口放在同一模块或由同一源文件生成不能再维护一份永远落后的副本。状态FACTS_COLLECTED表示候选包版本、注册表和材料索引已经收集不表示页面在运行时一定可达。实际项目可以在测试构建中提供只读诊断页按 featureId 执行导航 smoke test正式包不需要暴露内部列表。页面生命周期结束后要清理测试订阅和临时文件不能为了审核工具在生产环境常驻调试服务。四、版本事实要从候选产物链路采集最危险的做法是脚本读取开发者手填的另一个version.json。如果它和实际构建配置不同只会让两个错误文件互相证明。ReviewPathGate 要求 CI 在候选构建完成后生成candidate-facts.json内容来自当前工程配置和产物检查步骤审核清单只与这份事实文件比较。脚本本身不硬编码某个 DevEco Studio 目录结构。不同工具链版本的输出路径可能变化CI 应把事实文件路径作为参数传入。若找不到候选事实结果是FACTS_MISSING并阻断而不是回退到 Git 分支名推断版本。这段代码解决什么问题逐项比较审核清单与候选包事实、路由注册表和账号别名输出稳定的发现项而不是模糊日志。typeFinding{code:string;field:string;expected:string;actual:string}functionaudit(manifest:ReviewManifest,facts:CandidateFacts):Finding[]{constout:Finding[][]compare(out,BUNDLE_MISMATCH,bundleName,manifest.bundleName,facts.bundleName)compare(out,VERSION_NAME_MISMATCH,versionName,manifest.versionName,facts.versionName)compare(out,VERSION_CODE_MISMATCH,versionCode,${manifest.versionCode},${facts.versionCode})if(!facts.allowedAccountAliases.includes(manifest.accountAlias)){out.push({code:ACCOUNT_ALIAS_UNKNOWN,field:accountAlias,expected:registered alias,actual:manifest.accountAlias})}for(constfeatureofmanifest.features){constregisteredfacts.features.find(itemitem.idfeature.id)if(!registered||registered.route!feature.route){out.push({code:ROUTE_NOT_REGISTERED,field:feature.id,expected:feature.route,actual:registered?.route??missing})}}returnout}演示初始发现项为 4说明版本仍是 3.5.2、versionCode 30502、route 指向旧页面、账号别名未登记。修复后清单和候选事实都变成3.6.0 (30600)、/pages/InvoiceImportPage与reviewer_primary发现项归零。比较函数只输出别名和字段不输出密码。即使 CI 日志被下载也不应该包含可登录信息。实际项目还应对报告访问范围和保留周期做限制。五、可达性不是字符串相等需要最小 smoke testroute 在注册表中存在不代表功能真的能走通。页面可能依赖登录、远端开关、初始化数据或权限。ReviewPathGate 把四个步骤映射为可观察动作在测试环境使用虚构账号和固定演示文件执行最小路径进入发票中心、点击导入、选择演示文件、确认预览。这里不做像素级自动点击也不声称替代完整 UI 测试。应用在调试构建中为每个 actionId 暴露可查询状态测试驱动真实业务方法并等待稳定结果。任何步骤超时都记录在对应 action 上页面退出后取消等待器防止旧回调污染下一次测试。这段代码解决什么问题用 generation 隔离一次审核路径探测确保旧步骤回调不会把新一轮结果误标为通过。classReviewProbe{privategeneration0privatestate:IDLE|RUNNING|PASS|FAILEDIDLEasyncrun(feature:ReviewableFeature):Promisevoid{constcurrentthis.generationthis.stateRUNNINGtry{for(constactionoffeature.actions){awaitprobeAction(action,3000)if(current!this.generation)return}this.statePASS}catch(error){if(currentthis.generation)this.stateFAILED}}cancel():void{this.generationthis.stateIDLE}}状态在四步完成后进入ROUTES_PROBED。cancel()与页面离开成对调用generation 让晚到 Promise 失去提交权。实际项目的probeAction应走可测试的业务接口不要通过全局单例直接修改 UI 状态涉及网络时固定测试租户和数据集并明确失败是环境不可用还是功能错误。上图是 DevEco Studio 风格的演示配图不是实际 IDE 截图或审核证据。左侧显示 manifest、schema、route registry 和审计器中间是版本、路由比对逻辑右侧模拟器显示REVIEW-PATH-0069底部 HiLog 记录findings 4→0与exitCode 2→0。六、材料一致性检查要抓“引用关系”截图文件存在还不够。ReviewPathGate 为每张截图维护 sidecar 元数据记录 featureId、versionName、locale、deviceClass 和 captureSet。脚本验证截图是否属于invoice_import、是否来自 3.6.0、是否覆盖清单列出的页面。它不分析图片内容也不把生成图当成真实运行证据。审核说明中的按钮名称可能本地化actionId 则保持稳定。中文材料可以写“导入发票”英文材料写“Import invoice”两者都引用tap_import。这样文案调整不会导致路由脚本误判同时本地化材料仍能逐项复核。演示将材料事实收敛为 12 项3 个应用身份字段、1 个账号别名、1 个功能、1 条路由、4 个步骤、2 张截图最终覆盖12/12。这个数字只表达清单覆盖率不代表审核通过概率。七、运行页展示的是“提交准备度”ReviewPathGate 页面标题为“审核路径门禁”。它显示任务REVIEW-PATH-0069、bundleName、版本、功能 ID、route、账号别名和步骤数。当前状态MATERIAL_MATCHED进度 92%表示结构、候选事实、路由与材料已完成匹配等待最终报告签名。红色标注只指向/pages/InvoiceImportPage和12/12让读者看到门禁依据。页面不会显示密码也不会提供“一键登录真实审核账号”。按钮“生成提交报告”只导出脱敏 JSON 和摘要凭据仍由人工在受控流程中提供。09:21、Wi-Fi、5G、71% 电量属于演示视觉口径。实际审核材料的设备与时间应来自真实采集记录不能用这张生成图替代商店截图或审核证据。八、诊断页必须保留修复前后的差异如果工具最终只显示绿色 PASS团队无法知道门禁解决了什么。诊断页保留初始 4 项VERSION_NAME_MISMATCH、VERSION_CODE_MISMATCH、ROUTE_NOT_REGISTERED、ACCOUNT_ALIAS_UNKNOWN修复后同一任务 findings 变为 0exitCode 从 2 变为 0。状态链完整显示MANIFEST_LOADED → FACTS_COLLECTED → ROUTES_PROBED → MATERIAL_MATCHED → PASS。红圈标出4 → 0和exitCode 2 → 0。这比“审核材料已检查”更有可追溯性也方便定位哪次版本变更引入了路径漂移。报告还记录候选事实摘要c8e4但不记录文件绝对路径和凭据。摘要用于确认页面看到的报告与 CI 产物属于同一轮不承担密码学签名或供应链证明若需要更高保证应使用组织现有的制品签名方案。九、门禁如何接入发布流程最简单的接入点是在候选 HAP 构建后、上传前执行 Node.js 审计脚本。命令读取review-manifest.json、schema、candidate-facts 与截图 sidecar生成review-audit.json。发现项大于零返回 exitCode 2环境或输入缺失使用另一个退出码避免把工具故障误判为材料错误。脚本不应自动修改清单。自动把旧版本号替换成新版本看起来省事却可能掩盖说明文本和截图仍属于旧功能。门禁只报告差异由负责人判断更新材料还是回退候选包。修复后重新运行新的报告覆盖当前任务的临时输出但历史报告作为发布记录保留。CI 中还应固定 Node.js 与依赖锁文件JSON Schema 校验器升级时运行样例库。审核 FAQ 和平台字段可能变化规则配置要记录更新时间遇到无法验证的政策项只在报告里标记MANUAL_REVIEW_REQUIRED不能凭脚本猜测合规结论。十、把“可审核”当成一个工程接口ReviewPathGate 最终解决的不是审核平台本身而是团队内部材料与候选包之间的事实漂移。结构化 manifest 说明要测什么应用注册表说明入口在哪里candidate-facts 说明提交的究竟是哪一版smoke test 说明四步能否执行sidecar 说明截图属于哪个功能和版本。演示从版本 3.5.2/30502、旧 route 和未知账号别名出发得到 4 个发现项修复到3.6.0 (30600)、/pages/InvoiceImportPage和reviewer_primary后12/12 事实匹配状态进入 PASS。它是工程示例不代表真实商店审核结果。提交前的最小复核包括manifest 不含密码版本事实来自候选产物链路路由注册表与真实导航共享来源步骤使用稳定 actionIdsmoke test 的监听和超时能够释放截图 sidecar 与版本一致失败报告不被自动吞掉官方审核要求仍由人工按当前日期复核。当审核说明成为可验证接口团队就不必在每次发布前重新“相信某份文档应该没问题”。脚本给出可复现事实人工负责政策判断和最终材料质量两者分工比一份万能检查表更可靠。1. Schema 要验证结构也要拒绝多余字段审核清单属于发布输入拼错字段时不应被静默忽略。JSON Schema 可以对顶层和 feature 对象设置additionalProperties: false将versionCodee这样的笔误直接变成结构错误。步骤数组设置最小项数和uniqueItemsroute 使用受控 patternaccountAlias 限制为普通标识符避免有人误把邮箱或密码贴进去。Schema 本身也要有版本。清单新增captureSet等字段时提高 schemaVersion并为旧清单提供显式迁移脚本。迁移结果必须经过人工 diff不能在 CI 中悄悄改写源文件。结构变更和业务事实变更分开提交审核更容易。2. 测试账号管理必须与报告彻底分离reviewer_primary只是一把查找钥匙。CI 校验允许列表时只知道它存在、用途为审核、尚未过期不读取密码。真正提交材料时由有权限的人从密钥系统获取或在平台安全字段中填写。报告不能回显账号、密码、验证码种子或登录 token。账号轮换时先登记新别名并完成 smoke test再更新 manifest最后撤销旧账号。若先删除旧身份当前候选的路径测试会失去基线若长期保留多个别名又会扩大暴露面。门禁可以检查 expiry 和 owner 字段是否存在但凭据是否满足组织安全策略仍需人工确认。3. 环境不可用与功能失败要使用不同结论测试租户维护、演示文件缺失、远端服务超时都可能让路径探测失败。工具应区分ENVIRONMENT_BLOCKED与FEATURE_FAILED前者说明当前无法形成审核结论后者说明已到达应用但业务动作不符合预期。两者都阻断上传却需要不同负责人处理。不要在环境失败时沿用上一轮 PASS。每份报告绑定 taskId、候选摘要和生成时间旧结果不能证明新包可达。若必须离线提交清单应明确哪些步骤只能人工验证并把状态设为MANUAL_REVIEW_REQUIRED而不是绿色 PASS。4. 路由注册表需要明确所有者功能开发者在新增或迁移审核入口时负责更新 registry发布负责人只维护 manifest。这样 route 事实来自代码所有者材料意图来自发布流程。若两者都由发布人员临时修改脚本可能让错误路径“自洽”却仍无法运行。代码评审中可以要求路由变化同时更新对应 feature 测试。删除页面前先检查是否仍被 manifest 引用发现引用时CI 给出ROUTE_NOT_REGISTERED和 featureId而不是等提交当天才由人工发现。注册表只包含稳定业务入口不应把临时调试页纳入审核路径。5. 本地化材料要共享 actionId而不是共享文案按钮文案会随语言和产品迭代变化actionId 才是稳定关联键。每个 locale 的说明文件将tap_import映射为本地化文本脚本检查四个 action 是否都有文案和截图引用。中文缺一条、英文多一条都会形成发现项但不会要求不同语言显示完全相同的字数或布局。截图 sidecar 还应记录语言和设备类别避免把中文手机图误用于英文平板材料。图片内容仍需人工打开检查脚本只验证元数据与引用关系。生成式演示图可以用于技术文章说明不能冒充真实应用审核截图本文四张配图正是演示素材不进入商店提交集合。6. 报告需要稳定、可比较、可归档review-audit.json中每个 finding 使用固定 code、field、expected 和 actual排序也保持稳定。这样两次报告可以直接 diff不会因为对象遍历顺序变化产生噪声。报告摘要c8e4来自规范化后的非敏感事实任何输入变化都会生成新摘要。归档时把 manifest、candidate-facts、schema 版本、报告和截图 sidecar 放进同一发布记录但不包含凭据。若审核过程中平台要求补充说明新的材料创建新的 report generation不覆盖原始记录。这样团队能回答“哪一版包、哪一份路径、哪次修复产生了当前提交”而不是只剩一张绿色截图。7. 上线前做一次人工反向走查自动门禁通过后安排未参与功能开发的人按审核说明从头走一遍。操作者只能看到提交材料不能依赖内部口头知识。若他需要询问“发票中心在哪里”或“演示文件放哪”说明清单结构正确但文字仍不够可执行。人工走查还应验证退出、重试和空状态。审核人员可能输入错误一次、返回上一页或遇到网络抖动应用不能因此进入无法恢复的页面。工具负责事实一致最终体验仍要由人观察二者一起完成才是真正的提交准备度。走查结果也应回写为报告中的人工签名项只记录操作者、时间和结论不记录测试密码。这样自动检查与人工判断共享同一批次编号又不会混淆各自责任。参考资料鸿蒙应用审核 FAQHarmonyOS 上架审核相关开发者主题JSON Schema 官方站点
返回列表