测试用例怎么选:把风险变成一张矩阵

用例不是功能清单的展开

把每个按钮、每个字段、每种浏览器都乘在一起,得到的是组合数量,不是风险覆盖。发布前真正要回答的是:这次改动之后,哪些失败会让用户丢数据、看错状态、无法完成任务,或把内容送给不该看见的人。用例从这些失败往回选,而不是从界面元素往外乘。

测试用例怎么选,把风险变成一张矩阵
测试用例怎么选,把风险变成一张矩阵放大图解 ↗

矩阵用来把选择摆在明处。行是失败情景,列是条件,格子里写必测、抽样或不测,以及不测的理由。旁边再写清判定依据:怎样算通过。没有判定依据的格子,执行的人只能写看起来正常,回归就无法重复。

风险可以分成两列来估,但不要把乘积当成精确分数。一列是影响:失败之后用户会遇到什么,数据能否恢复,影响是一个人还是一批人。另一列是可能性:这次差异是否碰到这条路径,历史上这里是否出过问题,逻辑是否分散在多个入口。影响大而可能性低的格子,仍然可能要测,因为一次失败的代价盖过了发生次数。影响小而路径稳定、近期没有改动的格子,可以抽样,甚至写明不测。分数只是交谈的次序,不是自动取舍的开关。

行从失败情景来,不从页面截图来

一行描述一件会失败的事,以及它对外的表现。例如:重复提交之后出现两篇相同的稿件;定时发布的稿件在退回之后仍然发出;超长标题把操作按钮挤出可点击区域;审阅者能打开仅撰写者可见的草稿;网络超时后界面显示成功,库里却没有记录。这些句子里同时有条件和可观察的结果,可以直接变成行。

页面截图提供的是控件清单,适合用来查遗漏,不适合当作行。同一个提交按钮,在草稿、已排期、已发布、已退回上代表不同的状态迁移。若只写一行提交按钮可点,四种迁移会被压成一次点击。行应写成迁移:从哪个状态,经过哪个动作,到达哪个状态,哪些人可以做。

历史缺陷是现成的行。线上出过的问题,至少留下一行,直到有更低层的测试稳定地守住同一条不变量。下层守住之后,界面上的格子可以改成抽样,但行不要删掉,删掉之后没人记得这个不变量曾经被用户碰到过。

改动范围用来裁剪,不用来否定影响。差异只改了标题样式时,与标题长度、换行、放大字号相关的行要留下。与支付无关的样式改动,不必把全部支付通道重新测一遍,但若标题组件被发布页和支付页共用,就要看发布页上的标题失败会不会挡住支付入口。共用组件是行被带进来的原因,要写在格子旁边,避免下次有人因为差异看起来很小而把行抽掉。

列是条件,不是环境清单的堆砌

条件选择那些会改变结果的因素。角色改变权限。数据形状改变边界:空值、单条、刚好到达长度上限、超过上限、只有图片、只有正文、标题里夹着长串不换行的型号。状态改变允许的动作。网络改变完成与失败的外观:正常、超时、重复请求、响应先到而页面已经离开。端改变可达性:键盘、触屏、窄视口、放大字号。浏览器引擎在确实依赖引擎差异时才单列,例如某条布局只在一种引擎里溢出,而不是默认把三种引擎都乘上去。

列与列若会互相改变含义,就不要假装它们独立。放大字号加上窄视口,和各自单独出现,不是同一件事。这种交叉若影响大,就单独成为一列或一行,名为窄视口且大字号,而不是指望两列的抽样碰巧撞在一起。

时间也是条件。跨日的定时任务、时区、夏令时、任务延迟到达,都会让同一条发布规则产生不同结果。若产品按用户时区发布,矩阵里应有一行写明时区与服务器时区不同。只在编写者所在时区的下午点一次立即发布,测不到这条。

格子里写覆盖级别和判定依据

每个要讨论的交叉写三种级别之一。必测:这次发布前要执行,失败则不能发布。抽样:在一组等价条件里选一个代表,代表的选择写下来。不测:写理由,例如路径未被这次差异碰到,且下层契约测试已经锁住不变量。空格子表示还没决定,不要留到执行当天。

判定依据用可以复核的观察来写。库里只有一条对应记录。界面状态文本从已排期变为已退回。响应状态表示失败,按钮恢复可点,草稿仍在。通知没有发给退回之后的稿件。不要写工作正常、样式正确这种无法复核的话。视觉类的行可以把依据写成:在指定视口宽度下,横向文档滚动宽度不大于可视宽度,并且标题全文能在详情里读到。比一眼看去对齐更不容易随执行的人改变。

同一条依据若已经被接口测试或数据库约束保证,界面行就不要再复制一遍相同的断言,除非界面会把接口的失败显示成成功。矩阵里最浪费的格子,是三层都在断言同一件不可能发生的事,却没有格子断言界面把错误说成了成功。选择用例时,专门找这种说成成功的风险,它们不会被下层的拒绝结果自动覆盖。

用发布稿件的例子把矩阵摊开

下面是一张缩过的矩阵,对象是稿件从草稿到发出的路径。列只留了会改变结果的条件。级别用文字而不是分数。

失败情景撰写者审阅者超时与重复提交窄视口和大字号判定依据
重复点击产生两篇稿件必测不测,无此入口必测不测,与布局无关只存在一条稿件记录,第二次提交被拒绝并说明原因
退回之后定时任务仍发出抽样,看界面提示必测不测不测到达预定时间后状态仍为已退回,没有公开地址
超长标题挡住提交必测抽样不测必测提交控件在视口内可被键盘到达,标题全文可在详情阅读
审阅者打开他人未提交草稿不测必测不测不测得到拒绝,页面不展示正文
超时后界面显示已发布必测必测必测不测界面表示未完成,记录不存在或仍为草稿,可以再次提交
只上传图片、正文为空必测抽样不测抽样按产品规则拒绝或允许,规则文本与记录内容一致

这张表故意不大。撰写者与审阅者对同一情景的级别可以不同,因为入口不同。超时列只在结果可能被误报为成功时必测。布局列只在失败会挡住任务或切掉信息时必测。空下来的交叉写了不测的理由,阅读的人可以反对理由,但不能假装这个交叉没有被考虑。

若再增加浏览器引擎,不要把表乘成三倍。先问哪一行的判定依据依赖引擎。超长标题那一行若已经在一种引擎的近期缺陷里出现过,就把该引擎标成必测,另两种抽样。其余行保持不动。矩阵变宽是有理由的,不是出于完整的习惯。

组合太多时怎样收缩

四个角色、五种数据形状、三种网络、三种视口乘起来,会得到一大片执行不完的格子。收缩时保持影响最大的那一列全部分级,其余列做配对:让每两个因素的每种取值组合至少出现一次,而不是让全部因素同时穷尽。配对的前提是因素大致独立。已知会叠加的因素,例如大字号和窄视口,先合并成一个因素再配对。

边界值不要再用配对抽掉。空标题、到达上限的标题、超过上限一个字、没有空格的长串,这些不是等价类里随便挑一个就能代表的。等价类内部可以抽样,边界本身是行,保留。

状态迁移不要只测到达状态,还要测不允许的迁移。已发布的稿件不应再被草稿保存覆盖;已退回的稿件不应被旧的定时任务发出。不允许的迁移在矩阵里常常被漏掉,因为界面上没有那个按钮,测试就认为无事可做。接口仍可能接受旧请求。行可以写成:过期页面上的再次提交不得覆盖新状态。

下层测试改变格子的级别

单元测试和契约测试锁住一条不变量之后,界面对应的格子可以从必测降为抽样,但不能在同一天把行和测试一起删掉。降级要写明:哪条测试、断言了什么、不覆盖界面的哪一部分。界面仍可能把失败显示错,所以至少保留一条从界面走到拒绝结果的抽样。

反过来,只有界面测试、没有下层约束时,不要用大量界面格子代替约束。同一条不能重复发布的规则,若只靠人在三种浏览器里点两下,规则一旦换入口就会丢。矩阵评审时看到同一依据被复制到很多格子,就把依据下沉,格子回收。

不稳定的测试占用必测名额。一条时好时坏的界面测试,失败时没人敢当作发布阻塞,通过时也不能增加信心。它不应继续占着必测。先隔离,修好判定依据或等待条件,再放回。用增加重试来维持绿色,会让矩阵看起来覆盖很高,实际没有一条稳定的观察。

矩阵怎样随着迭代活下去

每次发布前读三样东西:这次差异碰到的行、上次缺陷留下的行、级别仍是空着的格子。不要每次把整张历史表从头点一遍。从头点一遍的结果是时间不够,执行的人私下跳过,表上却仍然写着必测。

新增行的门槛是出现了新的失败方式或新的条件,不是出现了新的按钮。按钮若只是旧迁移的另一个入口,在原行的判定依据里加一句从该入口触发即可。条件若不再存在,例如下线了某种角色,列可以退役,退役日期写在表头注释里,避免以后的人把列加回来。

执行记录贴在格子上,而不是另起一份谁也对不回矩阵的清单。记录包含日期、版本、执行的人、通过或失败、失败时的观察。失败的格子在修复后要重新执行,不能用相邻格子的通过代替。相邻格子的条件不同,代替就等于改写了矩阵。

抽样格子要记录这次抽到的代表。每次都抽同一条最短标题,等价类的其余部分从未被看见。可以按版本轮换代表,并在数据形状那一列注明轮换顺序。轮换不是随机点击,顺序写出来,下一次的人才知道哪一种数据还没有当过代表。

探索和矩阵互相指向

脚本化的格子覆盖已知情景。探索用来发现矩阵里还没有的行。探索章程可以写成:在窄视口下,只用键盘,尝试把一篇含长串型号的稿件从退回改到再次排期,留意焦点、滚动和重复请求。章程有时间盒。结束后把新发现收成行,没发现也记一句,避免下次重复同一章程却以为没有人走过。

探索不替代必测格子。必测来自已知的高影响失败,不该被这次没有碰到问题的探索取消。探索的价值是提出新行,例如发现后退返回后表单再次提交会覆盖审阅意见。那一行应进入矩阵,并补上判定依据,而不是只留在聊天记录里。

选择本身需要被审阅

矩阵在执行前给没有编写它的人看一次。审阅的问题是:有没有影响大的失败没有对应的行;不测的理由是否建立在已经不存在的下层测试上;判定依据是否能在失败时被观察到;必测是否多到必然被私下跳过。若必测多到发布窗口里做不完,就重新分级,而不是希望执行时加速。加速会先丢掉最难准备数据的那些行,那些行往往影响更大。

数据准备是选择的一部分。一行若需要一种很难造出的状态,执行时就会被跳过。要么在测试环境提供到达该状态的办法,要么把依据下沉到可以构造状态的下层测试,界面只留抽样。写进矩阵却无法准备的行,是虚假覆盖。

把风险变成矩阵之后,取舍还在,但取舍看得见。看得见的不测,比一份谁也执行不完、因而谁也不知道实际测了什么的长清单更可靠。下次发布时,人们改的是格子和理由,不是重新从功能清单乘出另一堆用例。

见字如晤

图解