无论是肯定的回答还是否定的回答,只要能够自圆其说我都可以接受,但是迷茫,说明没有意识到过这个问题。
而这个问题是“用例设计”所必须关注的,如果你不考虑全不全的问题,那也就无所谓“设计”,你只不过是在按部就班的把砖头从这里搬到那里而已。
能够进行良好的测试设计,才是高级工程师的开始。还记得上一篇我说过,初级工程师学习测试技术,中级工程师关注业务,高级工程师关注的就是设计。
也只有能够独立设计测试,才能带着工程师们干活,因为高级工程师是用例设计的底线,测试经理往往很少花精力去关注这些具体的工作内容,初中级工程师的用例质量是靠高级工程师们保证的。
虽然所有的测试工程师在这个问题上都会迷茫,但是经过短暂的迷茫之后,他们会有三种表现:
- 如果他们继续迷茫下去,他们最高也就是中级工程师;
- 有些人会告诉我,够了,然后尝试着自圆其说——能够说清楚的就是高级工程师;
- 还有些人会告诉我,好像不够,然后开始假装写用例的是另外一个家伙,开始批判,指出哪儿有问题,哪儿可以丰富。能够做到这一点的,我会想尽办法留住他。
那么,让我们回到刚刚的三个问题,为什么我会设计这样一道笔试题,然后设计这样三个问题呢?
刚刚我说过,这道笔试题只是第一部分,也是最没有价值的一部分,只要网上背个答案,过这个不难。真正有价值的是第二和第三部分。刚刚的过程中我并没有区分第二和第三部分,事实上,第二部分就是我让他们谈的部分,第三部分,就是当他们意识到自己的问题之后的表现。
第一部分是看他们平时工作的产出,第二部分是看他们理论与实际的联系,第三部分是看他们的自我批判能力,而这决定了他们的成长空间。
为什么测试用例要全面?
这个问题似乎完全不用回答,大家会笑着说,如果不全面的话,怎么保证质量?
这个话是相对正确的。只有全面的用例才能尽可能的保证产品质量。
但是用例集合中的元素是无限的,什么叫“全面”呢?
把所有的用例都写出来进行执行既不经济也不可能,用什么样的原则筛选出合适的用例呢?
上一篇文章我谈论过这个问题,我给出了两条原则,叫做“客户导向,因势利导”。
但是这只是业务上的原则,是在资源不足的情况下评定用例优先级的原则。但是第一步,我们需要从无限元素的用例集合中,选出有限个待选用例(或者子集),然后我们才能给他们排定优先级。
测试用例设计就是用来帮我们从逻辑的角度来找到这些用例。
我们都知道,测试用例包括黑盒测试用例设计(十五大方法)和白盒测试用例设计(六大覆盖)。现在,你知道他们是干嘛的了,我们就摘几个常用的聊一聊,他们的目的是什么,原理是什么,效果怎么样,适用于什么场景。
白盒测试用例设计方法
首先所谓白盒,是相对于黑盒而言的。盒是指我们规定的系统边界。这个边界是为了方便测试而对系统进行的划分。白盒就是盒子对你是透明的。也就是说,系统的边界虽然还在,但是你可以看到系统内部的执行逻辑。这就是白盒的白。
其实白盒测试用例设计本质上就一个方法,只不过依据覆盖方式不同而分成了六种覆盖方法,这六种方法的覆盖率不同。
白盒测试用例设计是建立在程序是串行执行的基础上,程序每次只能执行一条语句。如果我们把程序执行过的语句都抽象成一个节点,用线把这些节点连起来,我们就获得了程序的逻辑结构。白盒测试用例的设计思想就是,通过遍历程序逻辑的逻辑结构,保证无论程序是按照什么样的顺序执行,都不会出问题。
举例来说,假如一个程序是顺序执行的,有五条语句,第三条语句是一个IF判断,那么在程序执行时,就会在这个判断处(第三条语句)发生分叉。由于程序只按照顺序执行一遍,另一个分支内的代码在本次遍历时完全没有被执行过(第四或者第五)。因此,对于每个IF判断,至少需要执行真和假各一次。
对于循环结构、多分枝结构的情况也类似,都是尽可能的把所有的结构都覆盖。
额外的,对于有复杂条件判断的情况下,不仅可以针对最终条件判断的结果的真假分别进行遍历,还可以针对每一个子条件的真假和真假的组合进行遍历。
所以白盒测试用例设计方法又被成为结构驱动型用例设计。
这种知识哪怕在2015年都是测试开发工程师的专美,普通的黑盒测试工程师做梦都想学习如何针对代码进行测试。然而事实上这些内容很简单,按部就班的做即可。我说的并不清楚,具体内容可以参考百度百科,别嫌弃,够用了。
黑盒测试用例设计方法
黑盒的意思与白盒相对,系统在边界处开始对我们不可见了。盒里到底有啥我们不关心,我们把这个盒抽象成一个点,这个点完成了一个算法,将输入转换成输出。我们关注的是,所有的输入都被按照规范转换成了正确的输出。
所以黑盒测试用例设计方法又被成为输入驱动型用例设计。
黑盒测试用例设计方法包括十五种,太多了,我挑三个说说得了。
第一梯队是两个,等价类和边界值。
这两个方法几乎覆盖了99%以上的测试场景。基本上是测试工程师必备技能,无人不知无人不晓。但是通过刚刚的面试题我们知道,理论与实际有着鸿沟。
等价类的目的就是抓重点,方法是把用例集合切成子集,再从中选出你喜欢的那个用例,原理就是同一类的输入对系统而言处理逻辑相同,差异极小,因此可以看成一类。这也是等价类中“等价”的意义所在。
边界值更简单,是由于程序的判断条件在处理边界值时会发生例如等于和大于之类比较的问题,还有例如溢出等故障,因此特别的,针对一个输入域的边界要着重测试,一般会选择左边界、边界和右边界。
由于黑盒方法的特点,程序的输入域等同于用例集合。因此等价类和边界值就最方便的结合起来,由等价类对用例集合进行切分,再在切出来的这些边界上应用边界值。
听起来是不是合情合理?但是为什么理论和实践之间会出现这么大的问题呢?
我的经验是,大多数测试人员忽视了两点:
第一,等价类划分的第一步是找到用例集合,也就是用户的全部可能输入。这一步几乎没有人去找过。事实上,从逻辑上说,程序接受的输入就是0和1的组合,也就是一串字节。这些字节我们可以通用的翻译成N个的ASCII码。那么,你可以从结构和内容两个维度来思考,结构一般就是长度,从0到无穷大;内容就是那个字节的值是多少。用ASCII码的好处在于它已经分了等价类,包括了控制字符、大写、小写、数字和特殊符号,直接使用即可。
第二,等价类的划分原则应当是MECE(不重不漏)。这是我借用了金字塔原理的原则。也就是说,对于一个集合,我们要把它切分成N个等价类,那么对于集合中的任意给定元素,它一定属于某一个等价类;把所有的等价类内的元素加起来,一定等于这个集合。这样,我们才能保证我们的用例是全的,而且是不冗余的。