有效测试的精髓在于控制变量

把大象装进冰箱需要几步?

把大象装进冰箱需要几步?

这一部分可以跳过。

我想要大象在冰箱里,所以先去动物园找一头大象,再找一个冰箱,把大象牵到冰箱旁边,打开冰箱门,然后把大象装进冰箱,再把冰箱门关上。所以是七步。


现在遇到一个Bug,最后大象没在冰箱里,可能是哪里有问题?

让我们来从头理一理:

  • 去动物园:动物园闭园,临出门有事没去成,走着去一天都没走到,车坏路上了……
  • 找大象:动物园没有大象,大象生病了,大象睡觉呢,大象OK但管理员不让牵走……
  • 找冰箱:动物园没有冰箱,冰箱坏了,冰箱太大/太小,冰箱OK但装满了……
  • 把象牵到冰箱前:也可以把冰箱搬到大象前,它俩要在很近的物理位置上,冰箱上面贴个老鼠把大象吓跑了……
  • 打开冰箱门:东西太满打不开,门好像冻上了,冰箱门封条老化掉下来了,一不小心太用力把门拽掉了……
  • 装大象:大象不愿意,我推不动大象,冰箱太小装不下,冰箱被大象踩漏了……
  • 关上冰箱门:门关不上,密封条掉了关不住,大象用鼻子把门拱开了,用脚踹开了,门掉了……

梳理完头都大了,我看到最终大象没在冰箱里,原因可能有N种,我怎么知道到底是哪里有问题呢?只能一步一步排查,顺藤摸瓜,终于发现是冰箱太小了根本没法装大象。但也只是我这次的发现,下次没准会找到大冰箱。于是我周而复始的找大象装冰箱,衍生了各种工具各种方法,有时成功有时失败。但我始终仍记得我的目的,是要得到“大象在冰箱里”这个状态。

城市里流传着我的传说,大家看到我会微笑,在背地里指指点点:“看,那就是那个往冰箱里装大象的傻子。” 我无所谓,哪怕被困在同一天,我也能找到精进的方法提高成功率。

又是毫无不同的一天,我在去动物园的路上摔了一跤,爬起来掸掸土,脑子突然灵光起来:“不对啊,我为什么要日复一日的装大象?” 于是跑去问给我需求的人,再问给他需求的人,一路追问下去,“老板想看一集动画片。”

Source:Love, Death & Robots S01E13 Ice Age

吃饭睡觉打豆豆,放羊娶妻生娃放羊……人生真是虚无啊……

缺陷不会凭空产生

抽象一下上面的段子可得出,用户想要做达成目标,必有以下几个要素:

  1. 对象:我、大象、动物园、冰箱
  2. 行为:我去动物园、我找冰箱
  3. 顺序:我先去动物园,再找大象

常见的缺陷模式

  1. 对象本身有问题:特殊数据、资源权限、数据的状态等。

  2. 触发条件没满足:可能是链路问题,比如弱网、防火墙拦截,也可能是触达对象的问题,比如拒绝服务、消息阻塞等。

  3. 做事情的顺序不对:线性流程跳过步骤,不按顺序,任意流程节点回退;可并行的流程各环节的状态变化干扰等。

  4. 环境问题:环境不可用、不稳定、不满足测试条件等。

  5. 以上情况的一种或多种随意组合:这种就自求多福了,有经验的测试会减少试错成本。

今年冬天北京罕见低温,摩托仪表盘全线罢工;春暖花开了,它也结束了冬眠,不药而愈……

缺陷的产生不是玄学

之前和几个同事出差在外,租了一辆车,我们喜欢在通勤路上听歌。开始连蓝牙没问题,后来想添加连接设备时,整个蓝牙按钮都置灰了,导致我们无法对蓝牙设备进行任何操作,各种重启也无效,遂放弃。

一天我们去购物,同事Shawn在车里等候。刚拉开车门,他就眉飞色舞的说蓝牙修好了。我们不信,问他怎么修好的。“说起来你们可能不信,我上官网搜了一下,打开车门五分钟再关上就修好了,就是天比较冷,晚上我得多吃点。”

来自官网论坛描述

“Open the door 5 minutes” trick 包含以下步骤:断开蓝牙设备、熄火、打开车门五分钟、关门、启动。按照这个步骤确实可以修复这个问题,但我们并不知道重现或修复这个问题的最小步骤。无法稳定的重现问题,就说明我们不知道问题到底是什么。也许单纯是车载软件的问题,也许是硬件的问题导致软件没有进入正常的蓝牙状态,也许软硬件都有问题,是多缺陷导致的软件失效。

事出反常必有妖,缺陷的产生绝不是玄学。之所以无法重现问题,说明我们还没有找到导致缺陷产生的必要条件。如何找到呢?答案就是本节大标题:控制变量。

测试的精髓在于控制变量

一种科学研究方法

现实世界中,一个问题往往与多个因素有关。我们都知道不能穷尽测试,所以往往只会关注一两个影响结果的因素。那么问题来了:可能存在其他的因素影响结果。为了排除其他因素影响,虽然不能重点关注,但我们也需要考虑可能影响结果的其他相关因素。

控制变量就是这样一种科学的研究方法,可以把多因素的问题转化为多个单因素的问题,在单次实验中只研究某一个变量对结果的影响。当我们需要进行一些试错或探索尝试时,控制变量就比较好用。

映射到测试场景,有效测试的精髓就在于控制变量。这就是为什么测试用例要原子化,在确保其他因素一致的情况下,每次只验证一个点,这才是有效的测试。

再思考一下常见的测试问题:怎么重现无法重现的Bug?是不是有点思路了。无法重现的原因就在于没有发现影响测试结果的那个唯一因素。我们需要采用控制变量的方法,逐一排查影响测试结果的因素,直到找到影响的唯一因素。注意,这里影响结果的唯一因素不是单一因素,也有可能是多因素的组合。下面我们会展开介绍一下如何进行这种测试实验。

Source: Earth, Moon, & Sun Photo by Kevin Gill/Flickr

控制变量:端到端逐一排查

先凭直觉。

有时候潜意识会帮助你返回最接近真相的答案,只不过你不相信直觉,绕了一大堆弯路。所以脑海里有了朦胧的想法,就先探索一下,往往会有意外收获。

接着排除人的因素。

毕竟相对于各种调试来说,找其他小伙伴试试能否重现还是成本较低的。我之前就遇到过 “在我这一直有问题,到开发那立马没问题” 的Bug。不同的人操作习惯差异较大,手快有手慢无,键鼠偏好也不同。也许最后就是软件的问题,但找人也是相对高效的控制变量的方法。

然后排除环境因素。

道理与人的因素一样,相对好排查差异性。

再进行单一因素控制变量实验。

找到影响结果的任何因素,确保其他因素不变,进行单一因素的控制变量实验。看似量大,但其实这样能确保每次都是有效测试。当然,如果你能明确知道多个因素之间没有影响,也能分别验证其对结果的影响,完全可以放在同一个用例里去验证,这样的测试也是有效的。

最后进行组合因素控制变量实验。

当单一因素都排查完,还没找到问题所在,那么恭喜你获得自求多福卡,有较大可能你的问题是由多因素的组合导致的。如果还有时间精力,可以进行多因素的组合实验,从而找到影响结果的因素组合取值。

如果已经进行了足够充分的测试,还是没定位问题,那就把问题放在暂缓区好了,还是要追求高性价比。

可能会有疑问:折腾这一大圈已经花费很多精力了,还谈什么性价比呀。其实在很多测试者脑子里,大家就是这么测试的,只不过可能没意识到,或者没像我一样把思考的过程写出来。对有经验的测试来讲,这个过程不过是电光火石的一刹那,并不会占用太多精力,因为过往的测试经验已经把这种方法形成大脑肌肉的机械记忆了。所以各位在跟测试沟通时,TA有可能偶尔发呆,请不要打断TA。

测试敏感度

面试QA的时候经常看到这类评价,“该候选人测试敏感度不错”,到底什么是测试敏感度?我认为的测试敏感度是:经过一定时间的测试工作锤炼后形成的、那种测试独有的“问题嗅觉”。拥有较好测试敏感度的人,能够在需求和设计阶段就敏锐的识别出潜在缺陷,能够在正式测试前对缺陷的分布有正确的预判,能够在质量风险还未明显暴露时就拉着团队未雨绸缪,能够在出现问题后快速的定位问题分析问题,促成问题的最终解决。

测试敏感度也不是玄学,是可通过刻意训练养成的。不同的人可能适合不同的方法,但总有一个量变引起质变的过程。关键在于不放过某一个疑点,刨根问底的找到答案。当然了,过程中也要平衡成本和收益,允许问题存在和懂得适时放弃,也是测试必修技能。

所谓的测试敏感度说穿了也就那么回事儿,无非是经验之谈,再加上一点的细心钻研,没有什么神秘的。

Pracice Makes Perfect