跳到主要内容

测试与排障

本页把“编译通过”与“用户在真机上真的能顺畅使用”分开。对于 VoxelViewer,后者更重要:Component3D 的首帧、材质资源、手势竞争和 Picker URI 生命周期不能只靠静态编译证明。

验证层次

层次验证内容不能替代
静态检查ArkTS 编译、公开类型、资源路径。Scene 可见性、手势和性能。
HAR 构建产物可生成,README/License 打包正确。独立宿主兼容性。
Demo 构建entry 能消费 HAR API。真机 Component3D 行为。
真机手动验证首帧、背景、光照、动画、双指手势、Picker。资产权威验证。
VFP Reader 验证容器/目录/CRC。VOX0/source hash 验证。

一次完整的验收顺序

  1. 构建:确认 HAR 与消费它的宿主工程都能编译。
  2. 挂载:真机打开预览页,空状态、背景和 Viewer 尺寸正确。
  3. 输入:分别导入小 JSON、典型 128³ JSON、VFP 1.2、VFP 1.3。
  4. 交互:单指旋转;双指平移、缩放、手指取消和结束;动画结束后立即重复操作。
  5. 视觉:浅/深背景、彩色/纯黑模型、网格开关、单位描边首帧和载入动画。
  6. 切换:连续导入两份不同模型、页面离开再进入,确保旧场景/描边不晚到。
  7. 失败:取消 Picker、空文件、超限文件、损坏 VFP、无 PRVW 的 VFP。

把第 2–6 步保留为目标设备的视频/截图或人工检查记录;性能问题和视觉问题需要这种证据才能复现。

推荐回归清单

Preview

  • JSON 小模型:可见、颜色正确、单指旋转,双指平移/缩放正确。
  • 典型 128³ JSON:不出现 AGP 残影,动画结束立即可操作。
  • VFP 1.3:URI 路径无 bad file descriptor,PMSH 缓存命中时可见。
  • 深浅背景:模型显色和网格可辨,不产生全局发灰或全黑。
  • 有/无 unitGridTexture:前者首帧 PBR 描边,后者仅验证回退可用。
  • 页面离开/重进:旧动画或边线不会附着到新 Scene。

Reader

  • 破坏 Header、Footer、DIR0、一个区段 CRC:validate() 都应拒绝。
  • 没有 PRVW:查询为 undefined,不影响 parse/validate。
  • 非 GLB 2.0 PRVWextractPreviewGlb() 拒绝。
  • 大于 64 MiB URI:Reader 与 Viewer 都应拒绝。

外置 UI 回归

  • backgroundMode = BUILTINBUILTIN_CUSTOMBUILDEREXTERNAL 四种模式均不遮挡 3D 内容。
  • loadOverlayMode = BUILTINBUILTIN_CUSTOMBUILDEREXTERNAL 均能经历 IDLE、导入、准备、动画、错误、隐藏。
  • EXTERNAL 模式下不应再出现 HAR 自带遮罩;宿主 Overlay 用 state.visible 驱动,错误后可显示 state.errorMessage
  • BUILDER 模式下 Builder 只替换卡片,仍由 HAR 管理遮罩可见性。

常见现象

症状可能根因检查与处理
导入提示成功但画面空白Component3D Surface 尚未挂载,或页面生命周期又加载了内置模型。真机日志检查 Scene 代际和 aboutToAppear 逻辑。
bad file descriptorURI 在异步读取完成前被调用方关闭/失效。只传 loadUri() 或 Reader URI API;不要延后自行读取。
黑色模型描边太明显走了旧 BORD 或调参曝光/环境光异常。先确认 PBR 网格纹理可用,再从默认 Tuning 回归。
描边晚出现unitGridTexture 没有首载前设置。使用宿主 $rawfile('voxel/voxel_grid.png')
VFP 预览与 JSON 光照不一致VFP 面方向适配或使用了不同 Render Tuning。核对同一 Controller Tuning 和 Z-up → Y-up 归一化。
双指结束跳动外层手势与 Viewer 同时更新相机。删除竞争手势,保留 Viewer 的合并更新。
grid_size 错误JSON 缺字段、非整数、超 128 或 data 长度不对。校验输入合同。
validate() 成功但不能标记为“可编辑”将容器 CRC 完整性误当成权威语义校验。使用完整格式工具恢复 VOX0/PAL0 并重算 source hash。
extractPreviewGlb() 报错文件没有 PRVW,或 PRVW 不是合法 GLB 2.0。findSection('PRVW');它是可选缓存,不是正式 GLB 导出。
自定义遮罩永远不隐藏宿主把 message 当作状态枚举,或未根据 visible 更新。state.visible 控制展示,用 phase 区分样式。

日志与错误记录

宿主建议记录:业务任务 ID、源名称、文件大小、输入类型、VoxelLoadResultgetLastError() 和 HAR 版本。不要把完整 URI、私有文件内容或用户资产原文直接写入持久日志。

调试命令:

./scripts/logs.sh --device <device-serial> --from 5m --tail 300

对于渲染视觉问题,构建成功和日志无报错都不是完成证据;必须在目标设备录屏或手动验收。

最小诊断信息

出现问题时建议一次性记录以下非敏感字段,便于定位而不泄露用户资产:

VoxelKit 版本
设备型号 / 系统版本
输入类型(JSON / VFP)与文件大小
调用入口(loadText / loadBytes / loadUri)
VoxelLoadResult(若成功)
Controller 状态、lastError
是否设置 unitGridTexture
背景/Overlay 模式与是否播放动画
复现动作与真机截图或短录屏

不要把完整 Picker URI、JSON 原文、VFP payload 或用户模型截图写入长期日志。它们属于用户资产或可能包含隐私路径。

需要升级而非绕过的问题

  • 需要程序化相机、自动旋转、体素编辑或 VFP 写回:不要访问内部 Scene,等待/设计独立公开能力。
  • 文件超过 64 MiB:不要修改 Reader 私有常量或绕过 URI 生命周期,使用服务端预处理、分发策略或未来流式能力。
  • 要验证 source hash/权威 VOX0:不要从 Viewer 的预览缓存反推,使用完整格式工具链。