单元测试 = 白箱测试? 这是很多人的想法. 一听到白箱测试, 就认为他就是单元测试. 或者认为单元测试时, 就是要用白箱测试的方法来进行.
事情是这样吗? 让我们继续看下去:
当我们要测试这个程序时
Stack push(Stack s, int key)
你会怎么测试呢? 你可能会考虑以下几种状况
(1) 空的 stack, 第一次 push
(2) 不是空的 stack, 然后 push 东西
(3) stack 是满的, push 个东西看会不会有问题
(4) 不是空的 stack, 然后 push 一个字符
(5) 不是空的 stack, 然后 push 一个指标
你所做的大多是根据程序思考逻辑, 或者是根据输入的值域来做参考, 来建立测试个案.
这些方式其实都是黑箱测试(用到了 use case testing 和 Equivalence Class Testing等方法, 可自行去网络上找详细介绍), 也就是不管程序内部如何被实作. 只根据行为和输入值域来开立测试.
那真正的白箱测试会是怎么进行呢?
基本上, 可以测试的状况有无限多种. 而白箱测试是要根据程序内容来决定要怎样挑最小可测试的集合.
那程序内有甚么东西, 可以让我们来做挑选的判断呢? 一般常见的是根据程控逻辑. 例如: 是否经过所有的叙述(statement); 是否经过程序所有分支等等.
如果以经过所有的叙述为例, 对于下面的程序
01: Stack push(Stack s, int key)
02: {
03: if(isFull(s)){
04: printf("Stack is full !!\n");
05: }else{
06: s.top = s.top + 1;
07: s.element[s.top] = key;
08: printf("Success push %d in the Stack\n", key);
09: }
10: return s;
11: }
你会找出这组路径, 来当作最小需要测试的集合, 然后对它建立其相对应的测试个案
path1: 01-02-03-05-06-07-08-09-10-11
test case 1:
push (s, 3)
path2: 01-02-03-04-10-11
test case 2:
push (s, 3) (repeat 10 times, 如果 stack 大小是10 的话)
push (s, 3)
(当然你可以只用test case 2, 因为它涵盖了 test case 1 的状况)
一般人通常不会先分析执行路径, 再找测试个案. 大多是根据一些准则, 找出测试个案就开始测试了. 所以一般单元测试是用黑箱测试方式在进行, 而非白箱测试.
那为何大家会有错觉单元测试 = 白箱测试呢?
那 是因为在进行白箱测试时, 对于一个大的系统要找出可执行路径, 会是一件很复杂的事情. 但是对于每个单元时, 这件事情变得比较容易, 比较有可能不藉由工具的辅助, 就能自己进行. 也就是说在单元测试时, 比较容易进行白箱测试. 可是不知怎么传的, 很多人就把这两个视为同义.
最新内容请见作者的GitHub页:http://qaseven.github.io/