一. 方法简介
不考虑安全性、性能等专项测试内容,通常的测试流程包括:冒烟测试,一轮测试,二轮测试,回归测试。其中冒烟测试主要验证整体实现与需求是否相符以及主流程是否通畅,而一轮测试则是对所有测试用例进行全量遍历,记录提交bug并根据其出现概率对代码质量及修复、上线时间进行评估。
随机漫步法相当于在冒烟测试和一轮测试之间增加一个测试阶段,这个阶段的操作是:
1. 列表从完整的测试用例中随机挑选10%-20%的功能点进行验证,功能点尽量分散,不要在一个模块恋战;
2. 验证完成后,像一轮测试一样记录bug并根据出现概率对代码质量和需要的测试时间进行预估;
3. 结束后,进入一轮测试,此时跳过在随机漫步阶段验证过的内容,只测试剩余部分。此后的流程和原先一致。
举个栗子,下面是一个项目的测试用例图。
这个需求可以划分为5个模块,每个模块内有若干子功能点,随机漫步的具体过程就是:
1. 分析需求,做出测试用例;
2. 计算用例总数,根据比例计算需要进行随机漫步的用例数;
3. 在测试用例上随机挑选待验证功能点作为随机漫步的用例,用例尽量均匀分散在个模块内;
4. 验证这些功能点,统计成功率等数据;
5. 此时随机漫步阶段结束,之后按一轮测试标准,正常进行剩余用例的测试;
二. 数学原理及优势
拿数理统计学方法类比,一轮测试将所有用例依次执行判断结果的过程相当于普查,而随机漫步方法则相当于抽样调查。而抽样调查的特点和优势是通过小部分的样本推算出总体的特征,用更小的成本、更少的时间对总体获取一个大致准确的判断。
项目代码中,一个函数、方法的代码量与其逻辑的复杂程度正相关,而逻辑的复杂程度和测试用例数同样正相关,所以可以假设每个测试用例点出现bug的概率是一样的。设用例总数为N,随机漫步选取用例数n,其中发现bug数为x,那么项目质量的大致预期就是x/n,一轮测试后总bug数大致估计为N*x/n。此外,由于用例是随机选取均匀分布的,bug分布多的模块意味着这很可能是质量的短板,后续测试中可以重点关注。于是,我们只用了一轮测试10%--20%的时间,就对改需求整体的提测质量有了大致的估计,可以更好的评估后续工时和上线排期,更高效的完成测试工作。同时由于随机漫步并不额外占用一轮测试的时间(测试过的用例在一轮测试时不需要再次测试),不会增加测试工作本身的工作量,可谓“不会赔本的生意”。越是复杂的需求,测试用例数量越多,随机漫步发挥的威力也越大。
以上面的项目为例,随机抽取了15个功能点作为随机漫步验证用例,假设其中模块2中选择的4个用例有3个有问题,模块4、模块5中各有1个有问题,其余测试通过。那么当前bug率就是1/3,其中模块2为重灾区。以此可以判断该项目质量令人担忧,存在更多问题的概率很大,需要预留更多时间让研发排查、优化代码,推迟预计上线时间,尤其是对于模块2,可能存在需求层面交流不充分之类的问题,需要重点检查。
三. 真实随机和纯粹随机
话说随机漫步法肯定不是我最先发明的,大概率也已经有人将其运用在测试工作中了,而我还“好意思”拿来做分享,主要是要介绍两个大家不太容易意识到的概念差异:真实随机和纯粹随机。当然,这俩概念是我自己定义的。
下面进入敲黑板划重点时间。假设现在需要你做一个抛一万次硬币记录结果的实验,在不借助实物和软件模拟的情况下让你纯凭借想象写实验结果你会怎么写呢?假设现在让你凭空写下你所在小团队(30人左右)每个人的生日,你又会怎么写呢?
如果从直觉出发,每次抛硬币正面和反面出现的概率都是二分之一,所以最后的结果应该是正反面均匀分散分布,如果用0表示反面,1表示正面,那最后记录下来大概是这么个意思:
序列1
01001100111101011010
10110101101000101101
00101101000110110010
10101100110011101000
10111101101111011100
00010010000110110101
10011001110101001001
01010001101110011110
00101101010100110100
而假设生日是在365天内随机分布的话,30个样本毕竟太少,最后记录的结果大概会是365天里随机抽取30天,然后让每个月里分布两三个。
但如果你真的去抛硬币或者去统计大家的生日的话,你会发现事实完全不是这样的。在抛硬币的实验里,肯定会出现很多连续正面或者连续反面的群块,大概像下面序列2这样:
序列2
01111010011011100111
11100101111011100111
00101100101000110000
01011011100110011111
11111000011111111111
00110001010000101000
01011000000010110011
11011100000010111011
11111110001011111100
这是因为,连续出现正面、反面虽然看起来概率小,但在一万次这样的基数下,“出现小概率事件”本身是大概率的。比如连续出现10次正面的概率只有1/1024,但同时这也意味着平均抛1000次就会出现一次连续10次正面的序列,而10000次里都不出现连续10次正面的概率只有0.74%!因此像上面序列1这样正反面分布如此均匀甚至连续5次正面或反面都没出现是绝无可能的。生日也是同理,看起来30个人的生日分布在365天里的“操作空间很大”,但经过计算就可以发现出现两个人生日相同的概率高达71%,从月份维度来看,出现5、6个人生日在同一个月内也是大概率事件。
产生这种差异的主要原因在于我们会“抓大放小”,只关注大概率而忽略小概率,所以最后的结果“随机过头”。现在我们把序列2这样现实中的随机结果称为“真实随机”,把序列1这样我们脑海中认为的随机结果称为“纯粹随机”。所以真实随机在大体上分布分散均匀,但经常伴随着一些聚集的小部分,而纯粹随机则均匀分布的更加彻底。
根据前二章的理论推导可以得出,为了使随机漫步法发挥其最大的效率,测试用例的分散程度应该尽可能的均匀,也就是纯粹随机,这是随机漫步最重要的心法。随机漫步给人的第一感觉是暂时忘记测试用例,在页面上随便点点看看,随手试试一些功能来做整体判断,但如果这样操作,一来很难记录测试过的用例需要等一轮再全量跑,二来这种操作下用例的分布是真实随机的,无法充分发挥其优势,对比参考下面两幅图可以有更直观的感觉。
同样是15个用例,两种随机方式对测试用例的覆盖程度有明显的区别。真实随机看似“随心所欲”,但这样全凭感觉的随机并不能真正反应出整体的全貌,会大概率出现“小概率聚集”,反而干扰对项目整体质量的判断。纯粹随机尽管并“不自由”,但理性的保证选取用例均匀分布,从而真实反应整体的质量。
因此,要真正做好随机漫步的关键,恰恰需要在开始测试之前全面深入的分析测试场景和用例,有目的性的选择随机案例使其分布更均匀达到纯粹随机。
总结:
1. 随机漫步是在冒烟测试和全量测试流程中间的质量探针,通过抽样测试提前分析整体质量,有利于更准确的预估测试进度和协调研发修复bug。
2. 随机分为真实随机和纯粹随机,在页面上随便点点看看的操作是真实随机,而要最大程度发挥随机漫步法的效率需要纯粹随机,这需要在开始测试之前全面深入的分析测试场景和用例。