过敏测试和软件测试

入春以来,鼻子痒,堵,流鼻涕,像感冒一样,其实是过敏。看了个耳鼻喉的专家,她的一番话,竟让我联想到了软件开发中的测试问题。就像Dijkstra说的,测试只能表明Bug的存在,而非它们的绝迹

过程是这样的,我做了一个抽血实验,指标说明我没有过敏。医生很耐心的跟我讲,抽血结果说你没过敏,并不代表你没过敏。因为抽血化验只针对一部分过敏原。结果是好的,只能说明你对这些物质没有过敏反应。并不能代表你对其他东西也不过敏。像什么狗毛了,猫毛了,花粉了什么的,并不在化验的范围内,所以你有可能对他们过敏。也没有必要做更多的测试,因为很可能你又测了十几种,还是没找到过敏原,也只能证明对这些测试的东西没反应,而说明不了全部。

话,绕来绕去,就是告诉我,我知道你对哪些东西不过敏,不知道你对什么过敏。这就像软件测试一样,你写了一个测试,我们只能知道,在这种情况下,软件会好用,但并不知道,在哪些情况下不好用。

我举个简单的例子,比如下面的冒泡排序

1
2
3
4
5
6
7
8
9
10
11
12
13
public class BubbleSort implements Sorting {

@Override
public <T> void sort(T[] elems, Comparator<? super T> comp) {
for (int out = elems.length - 1; out > 1; out--) {
for (int in = 0; in < out; in++) {
if (lessThan(elems[in + 1], elems[in], comp)) {
swap(elems, in, in + 1);
}
}
}
}
}

针对下面的输入,都能排好

1
2
3
Arrays.asList(2, 3, 4, 8, 5, 7, 1, 6);
Arrays.asList(2, 8, 3, 4, 5, 7, 1, 6);
Arrays.asList(5, 8, 4, 3, 2, 7, 1, 6);

但有一种情况排不好,你能看出来是为什么吗?

1
Arrays.asList(2, 3, 4, 8, 5, 7, 6, 1);

医生说,没必要做所有的测试,因为成本太大,并且不一定找到好的结果。但对软件测试而言,有没有好的办法呢。我是一个热情洋溢但比较笨的工程师,所以用了一种比较笨的方法,就是随机产生很多测试,暴力解决问题,这里你可以看得到,后来才意识到,在这种情况下,大家都在用一种叫基于属性的测试方法:Property-Based Test。有没有更暴力的呢,还真有,There are Only Four Billion Floats–So Test Them All!

一个过敏测试,一个软件测试,看上去两个没有联系的东西,可认真比较后,却惊喜的找到了他们的共同点。类比之后,反而对Dijkstra的那句话有了更加深入的理解。