云计算百科
云计算领域专业知识百科平台

【共创稿事节】HarmonyOS 7空间应用的可用性测试和体验评估小方法分享

空间应用最容易翻车的地方,不是功能没做出来,而是做出来之后没人能顺畅用下去。用户戴上设备、或者举起手机进入空间界面,三分钟内是兴奋还是头晕,决定了这个应用能不能留下来。可用性测试在 2D 时代已经有一整套成熟方法,问题是搬到空间里之后,哪些还能用、哪些必须加,以及怎么把"体验好不好"变成可比较的数字。

2D 那套方法,大部分能直接搬

别急着发明新流程。任务制定、出声思维(Think Aloud)、观察记录、事后访谈、SUS 量表,这些骨架在空间应用里依然成立。用户的认知负荷、信息查找、操作失误,底层机制没变。

能直接沿用的部分:

  • 任务式测试。给用户一个具体目标,观察他怎么完成,而不是问他"你觉得好用吗"。
  • 出声思维。让用户边做边说,卡住的地方往往比最终结果更有价值。
  • 完成率与完成时间。这两个客观指标在空间里同样有效。
  • 访谈与问卷。SUS(System Usability Scale)这类成熟量表不用改题,直接问。

需要调整的是环境和变量。2D 测试坐在桌前点鼠标,空间测试涉及设备佩戴、视野限制、身体姿态,测试的组织方式差别很大。

空间应用新增的四个维度

舒适度

用户能连续用多久而不感到疲劳,是空间应用的生命线。舒适度受视觉疲劳、颈部负担、设备压感共同影响。测试时不能只问"累不累",要拆开:眼睛干不干、脖子酸不酸、画面晃不晃。

晕动

晕动症(motion sickness)的成因是感觉冲突——眼睛看到画面在动,前庭系统没感受到对应的身体运动。空间应用里,相机加速过快、视野旋转与头部动作不同步、低帧率都会触发。评估晕动的标准工具是 SSQ(Simulator Sickness Questionnaire),它把症状分成恶心、眼部不适、方向障碍三类,用问卷打分。

可达性

3D 里的目标拾取比 2D 难得多。一个按钮在 2D 里是矩形,在 3D 里是空间中一个可能被遮挡、可能超出舒适区的物体。Fitts 定律在 3D 中的延伸告诉我们:目标距离越远、越小、越偏,拾取时间越长且越容易失败。评估可达性要记录"首次命中率"和"平均拾取时间"。

深度理解

用户在空间界面里,能不能正确判断元素的前后关系、层级关系?这一点在 2D 里几乎不用测,在 3D 里却是高频错误来源。常见测法:让用户回答"这两个卡片哪个更靠前",或者"要返回上一步应该点哪个",通过回答正确率衡量空间层级设计是否清晰。

一套可操作的指标与清单

维度指标采集方式参考目标
效率 任务完成率 观察记录 核心任务 ≥ 90%
效率 任务完成时间 埋点计时 与 2D 版持平或更低
效率 操作错误次数 埋点计数 单任务 ≤ 1 次
舒适度 连续使用时长 会话时长统计 无强制休息下 ≥ 15 分钟
舒适度 视觉疲劳评分 自评量表(1-7) ≤ 3
晕动 SSQ 总分 标准问卷 无中度以上症状
晕动 帧率稳定性 运行时监控 主流机型 ≥ 55 FPS
可达性 首次命中率 埋点统计 ≥ 85%
可达性 平均拾取时间 埋点计时 与 2D 点击接近
深度理解 层级判断正确率 插入验证题 ≥ 80%
整体 SUS 总分 标准量表 ≥ 70(良好)
整体 SEQ 难易度 单题访谈 平均 ≥ 5.5/7

这套指标的好处是:客观指标(完成率、帧率、命中率)用埋点采,主观指标(SUS、SSQ、SEQ)用问卷采,两类互相印证。如果客观数据很好但 SUS 很低,说明功能能用但体验别扭,问题在设计不在功能。

把测试数据采下来

评估不能靠记忆和印象,要在应用里埋点。下面是一个轻量的测试记录器,负责记录任务起止、耗时、错误数,并把主观评分一起写入本地文件供测试后回收。

import { fileIo as fs } from '@kit.CoreFileKit';

// 单次任务记录
interface TaskRecord {
taskId: string;
startTs: number;
endTs: number;
durationMs: number;
errorCount: number;
success: boolean;
seqScore: number; // 单项难易度 1-7
}

class UsabilityRecorder {
private static instance: UsabilityRecorder = new UsabilityRecorder();
private currentStart: number = 0;
private errorCount: number = 0;
private taskId: string = '';

static getInstance(): UsabilityRecorder {
return UsabilityRecorder.instance;
}

// 任务开始:测试脚本或业务代码在进入任务时调用
startTask(taskId: string): void {
this.taskId = taskId;
this.currentStart = Date.now();
this.errorCount = 0;
}

// 记录一次误操作,用于衡量学习成本
recordError(): void {
this.errorCount += 1;
}

// 任务结束:计算耗时并落盘
finishTask(success: boolean, seqScore: number): void {
const record: TaskRecord = {
taskId: this.taskId,
startTs: this.currentStart,
endTs: Date.now(),
// 耗时统计要排除加载等待,这里只覆盖交互阶段
durationMs: Date.now() – this.currentStart,
errorCount: this.errorCount,
success: success,
seqScore: seqScore
};
this.appendRecord(record);
}

// 追加写入沙箱文件,测试结束统一导出分析
private appendRecord(record: TaskRecord): void {
const path = getContext(this).filesDir + '/usability_log.jsonl';
try {
const file = fs.openSync(path, fs.OpenMode.CREATE | fs.OpenMode.APPEND | fs.OpenMode.READ_WRITE);
fs.writeSync(file.fd, JSON.stringify(record) + '\\n');
fs.closeSync(file);
} catch (err) {
console.error('usability log write failed: ' + JSON.stringify(err));
}
}
}

配合一个帧率采样,把晕动风险的客观数据也拿上。帧率掉到 60 以下时,画面迟滞会加重感觉冲突,晕动概率明显上升。

import { displaySync } from '@kit.ArkGraphics2D';

// 用 displaySync 采样帧率,低于阈值就计数,作为晕动风险的客观依据
function startFpsMonitor(onSample: (fps: number, lowFps: boolean) => void): displaySync.DisplaySync {
const sync = displaySync.create();
sync.setExpectedFrameRateRange({ expected: 60, min: 30, max: 120 });

let frames = 0;
let windowStart = Date.now();

sync.on('frame', () => {
frames += 1;
const elapsed = Date.now() – windowStart;
if (elapsed < 1000) {
return;
}
const fps = Math.round(frames * 1000 / elapsed);
// 60 是主流刷新率,掉到 55 以下时画面迟滞会加重感觉冲突
onSample(fps, fps < 55);
frames = 0;
windowStart = Date.now();
});

sync.start();
return sync;
}

测试流程怎么组织

空间应用测试比 2D 多出准备环节和恢复环节,流程大致是这样:

#mermaid-svg-hbHbWUI5B1WxKVAp{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-hbHbWUI5B1WxKVAp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-hbHbWUI5B1WxKVAp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-hbHbWUI5B1WxKVAp .error-icon{fill:#552222;}#mermaid-svg-hbHbWUI5B1WxKVAp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hbHbWUI5B1WxKVAp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-hbHbWUI5B1WxKVAp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hbHbWUI5B1WxKVAp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hbHbWUI5B1WxKVAp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-hbHbWUI5B1WxKVAp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hbHbWUI5B1WxKVAp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hbHbWUI5B1WxKVAp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hbHbWUI5B1WxKVAp .marker.cross{stroke:#333333;}#mermaid-svg-hbHbWUI5B1WxKVAp svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hbHbWUI5B1WxKVAp p{margin:0;}#mermaid-svg-hbHbWUI5B1WxKVAp .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-hbHbWUI5B1WxKVAp .cluster-label text{fill:#333;}#mermaid-svg-hbHbWUI5B1WxKVAp .cluster-label span{color:#333;}#mermaid-svg-hbHbWUI5B1WxKVAp .cluster-label span p{background-color:transparent;}#mermaid-svg-hbHbWUI5B1WxKVAp .label text,#mermaid-svg-hbHbWUI5B1WxKVAp span{fill:#333;color:#333;}#mermaid-svg-hbHbWUI5B1WxKVAp .node rect,#mermaid-svg-hbHbWUI5B1WxKVAp .node circle,#mermaid-svg-hbHbWUI5B1WxKVAp .node ellipse,#mermaid-svg-hbHbWUI5B1WxKVAp .node polygon,#mermaid-svg-hbHbWUI5B1WxKVAp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hbHbWUI5B1WxKVAp .rough-node .label text,#mermaid-svg-hbHbWUI5B1WxKVAp .node .label text,#mermaid-svg-hbHbWUI5B1WxKVAp .image-shape .label,#mermaid-svg-hbHbWUI5B1WxKVAp .icon-shape .label{text-anchor:middle;}#mermaid-svg-hbHbWUI5B1WxKVAp .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-hbHbWUI5B1WxKVAp .rough-node .label,#mermaid-svg-hbHbWUI5B1WxKVAp .node .label,#mermaid-svg-hbHbWUI5B1WxKVAp .image-shape .label,#mermaid-svg-hbHbWUI5B1WxKVAp .icon-shape .label{text-align:center;}#mermaid-svg-hbHbWUI5B1WxKVAp .node.clickable{cursor:pointer;}#mermaid-svg-hbHbWUI5B1WxKVAp .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-hbHbWUI5B1WxKVAp .arrowheadPath{fill:#333333;}#mermaid-svg-hbHbWUI5B1WxKVAp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hbHbWUI5B1WxKVAp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hbHbWUI5B1WxKVAp .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hbHbWUI5B1WxKVAp .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-hbHbWUI5B1WxKVAp .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hbHbWUI5B1WxKVAp .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-hbHbWUI5B1WxKVAp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hbHbWUI5B1WxKVAp .cluster text{fill:#333;}#mermaid-svg-hbHbWUI5B1WxKVAp .cluster span{color:#333;}#mermaid-svg-hbHbWUI5B1WxKVAp div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hbHbWUI5B1WxKVAp .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-hbHbWUI5B1WxKVAp rect.text{fill:none;stroke-width:0;}#mermaid-svg-hbHbWUI5B1WxKVAp .icon-shape,#mermaid-svg-hbHbWUI5B1WxKVAp .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hbHbWUI5B1WxKVAp .icon-shape p,#mermaid-svg-hbHbWUI5B1WxKVAp .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-hbHbWUI5B1WxKVAp .icon-shape .label rect,#mermaid-svg-hbHbWUI5B1WxKVAp .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hbHbWUI5B1WxKVAp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-hbHbWUI5B1WxKVAp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-hbHbWUI5B1WxKVAp :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

招募被试 含空间感差异

设备与安全说明

基线问卷 视力/前庭敏感度

熟悉环节 教基础操作

执行任务 出声思维

即时 SEQ 评分

休息恢复 缓解疲劳

SSQ 与 SUS 问卷

事后访谈与复盘

数据汇总 对照指标表

两个容易被压缩掉但很关键的环节:熟悉环节和休息恢复。空间操作有学习曲线,不做预热直接测,完成时间会被"不熟悉"污染。休息恢复则关系到后半段任务的数据有效性,用户疲劳之后的操作表现不能和前半段混为一谈。

案例:3D 商品浏览的两次测试

一个家具应用准备上线 3D 看货功能,团队做了两轮测试。

第一轮招了 8 人,用中端机测试。任务是把沙发转到背面看靠垫细节、再换个配色。结果完成率 75%,SEQ 平均 4.2,SSQ 里有 3 人报告了轻度眼部不适。埋点数据显示,转到背面这个任务平均耗时 11 秒,错误主要发生在"继续旋转"和"切换配色"两个按钮上——用户分不清当前手势是在转模型还是转整页。

分析后做了三处调整:把旋转手势限定在模型区域,区域外恢复页面滚动;把配色切换从隐藏菜单提到常驻操作条;把默认相机距离拉远一点,减少近距离注视引发的眼疲劳。

第二轮同样是 8 人。完成率升到 96%,SEQ 平均 5.8,SSQ 无人报告中度症状,SUS 从 62 升到 78。全过程中端机的帧率稳定在 58 FPS 以上。

这个案例说明一件事:可用性测试的价值不在"证明做得好",而在精确定位那几处让用户犹豫的地方。手势归属和按钮可见性,光靠设计评审很难发现,只有真人操作才能暴露。

总结一下下

  • 客观指标和主观问卷都要,单看一边容易误判。
  • 测前一定要有熟悉环节,别把学习成本算进任务时间。
  • 帧率数据要单独采,它同时影响效率和晕动,是最划算的一个埋点。
  • 被试要包含对空间感不敏感的人,只看"玩过 VR 的人"测不出真实门槛。
  • 插入少量验证题测深度理解,比只看完成率更能发现层级设计缺陷。
  • 任务设计要贴真实场景,"随便看看"这类模糊任务收集到的数据没有分析价值。
  • 只在旗舰机测试,忽略了应用实际覆盖的中低端设备,晕动和高延迟都被藏起来。
  • 用户强忍不适不好意思说,要主动、定时询问,不要等对方开口。
  • 拿 2D 的 SUS 基线直接对比空间应用,两者难度不同,对比要谨慎。
  • 任务时间没有排除加载等待,把网络耗时算进了交互效率。
  • 问卷当场填得太晚,用户已经忘了具体感受,主观数据要即时采。
  • 测试结束没有导出日志,埋点白做,分析只能靠回忆。
赞(0)
未经允许不得转载:网硕互联帮助中心 » 【共创稿事节】HarmonyOS 7空间应用的可用性测试和体验评估小方法分享
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!