I3.13.1complete transition coverage设计

状态机需要为所有可能的转移路径定义结果,不留未定义转移

别名: 完备转移 · 未定义转移 · total transition · 缺边

概念解释

界面背后有一张状态机:保存中、已保存、失败、离线排队。用户或系统发出的每一个在当前态上可能到来的事件,都必须有一条画好的边,边的另一头是一个合法态。不留未定义转移(undefined transition):没有「这个事件现在不该发生,所以我们没写」。没写的边在真实世界里照样会到——双击、晚到的网络回调、从后台回来、一次权限弹窗打断——到了却无去处,产品就掉进空白、死转圈、或一个谁也叫不出名字的画面。

这条管的是边上的完备,不管节点本身会不会被数据结构拼出非法组合。那是另一刀。

机制

状态机的完备性是全函数:对每个(状态 × 事件)都给出下一状态,哪怕下一状态是「忽略并留下」或「进入明确的错误态」。部分函数在纸面上干净,因为作者删掉了「不该发生」的格。运行时那些格会被填上:网络把「成功」送到已经取消的请求上,用户在「提交中」又按了返回,系统在「录音中」打来电话。未定义格没有下一状态,实现层只能走语言的默认——空指针、旧画面残留、或静默丢事件。丢事件之后,屏幕上的态和真实的态分叉,后续所有转移都在错的节点上算。

「忽略」也是一种定义。把它写出来,测试才能断言「在提交中按返回应停在提交中并提示不可离开」,而不是靠碰巧。未写出的忽略和未定义在代码里长得一样,只有事故能区分。

边界

理论上事件集合无限(任意时刻的任意手势)。完备针对的是产品承认的事件字母表:提交、取消、超时、成功、失败、进入后台、恢复、权限结果。字母表外的输入应在更外层被吞掉,不要漏进机器。分层状态机(Harel 的 statechart)允许在父态写默认处理,子态不必重复每一条——那是完备的一种写法,不是缺边。外部系统的事件可能迟到:字母表里要包含「迟到的成功 / 迟到的失败」,并把它们在已离开的态上定义为无操作或一次可忽略的日志,而不是当新的提交。演示用的快乐路径图不是状态机;用它当实现清单会系统性漏边。

怎么落地

  • 列出状态 × 承认事件的表,每一格填写下一状态或「忽略(原因)」。空格不许上线。
  • 把迟到回调、双击、返回、来电打断、权限对话框当作字母表里的一等事件,不要当异常。
  • 未定义一旦在日志里出现,先补边,再修画面。
  • 验证:在「提交中」分别做返回、再点提交、切后台、杀掉网络、让成功回调在取消之后到达。每一种都应落到表里写过的态,而不是转圈或白屏。任意一种让屏幕无法命名当前态,就是缺边。对照快乐路径:只测「提交 → 成功」通过,不能当作完备。

延伸

  • 同组I3.13.2 数据结构若允许表达不属于任何合法状态的组合,就会产生非法状态 · I3.13.3 非法状态的出现往往源于用多个独立布尔值而非互斥枚举描述状态 · I3.13.4 界面呈现的状态应与底层状态机严格对应,不能凭视觉猜测当前状态
  • 相邻I3.01 系统状态可见 · I3.09 乐观更新与回滚
  • 站内检索complete transitions · undefined transition · statechart

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/I3.13.1