由于 时间比较紧,以前某段c++代码只作了很简单的单元测 试。
在其中 隐藏了一个bug,该虫子影响了0.5%不到的数据。虽然早就知道有这个虫子,但一直没有时间来deal bug。
由于剩余的99.5%的数据还有很大的用途, 所以,比起这个捉虫更难以处理的是在保护正确数据基础上捉虫。
这个任务就显得很艰巨了。
于是先备份代码和数据。再为备份写了3行说明。再开始捉虫。
用了不到45分钟。虫就找到了。并改好了代码。重新构造了一段数据,用最后版本测试这段独立数据的整理,包括写测试代码。又花费了120分钟。
但是如何把原有数据进行有效重组,出现了大量的问题。
虽然新代码可以从原始0状态正确建立数据关系, 但新代码却不具备整理99.5%正确+0.5%错误数据混杂在一起的能力。
没有办法,只好先写出数据重新组合的代码来,这段代码很难写,因为它的加工对象是一堆内在很难排出条理的东西,而且还不能破坏那99.5%有用的数据。面对混乱,投鼠忌器啊。
第一个重组版本的代码出来了。长度是捉虫版本的5倍还要多。时间也花费了400多分钟。
但是,这个版本一出来,就出师不利,有2个内存问题,而由于内存问题,又导致99.5%的正确数据中有部分受到损失。还好,数据有备份。
用了16个小时左右的时间,终于把这两个隐藏很深的错误找到了。
但这段代码还有其他一些问题。他的重组还是不正确。
又用了3个小时,终于找到了另外的问题,有两行代码次序不正确。导致调用该函数的外部函数工作不正常。由于错误出现的部分只在0.5%的部分出现,所以每次跟踪都要花费很长时间。
又修正了这个问题。
重新写了两个测试函数,为了保险起见,又审核了测试函数。两个函数又分别测试了2个小时,确认结果无误。
于是找到原始数据版本,用重组代码重组了一次数据。还用测试函数测试了结果。
再次调用捉虫代码,向重组好的数据中插入新数据,删掉个别数据。测试函数报告:结果无误。由于问题一直隐藏很深,还是不敢确信,又写了一个新的数据输出到文件的函数,输出数据到一个文本文件,手工随机抽查了400个数据,没有问题。这个部分又是6个小时。
总结下来:1)内存错误,是最常见的错误。
2)要在错误还在萌芽状态,就消灭。本例子主要是错误比率太低,开始测试都没有发现,而且错误只表现在数据结果中很小一部分,程序自身又没有死掉等症状。所以问题发现得很晚。应该说还是原来的单元测试不充分。
3)时间比较:直接捉虫,含修改好代码,写好测试该部分修改的代码,数据测试,一共是不到3个小时。而数据重组的代码和测试分析等工作,超过了24小时。比例是1:8。这说明,问题越发现得晚,时间损失越大。这个是最大的教训。
4)当然,这次捉虫大行动,也不是一无是处。代码及时备份了,数据也及时备份了。还写了简单的备份版本说明。后来都用上了。一写好新东西,就开始为它写好测试代码,这种方法也派上了用场。
5)代码还比较清晰,发现问题本身还不是那么困难。(我用的是自然语言编程法)
6)希望以后只需要直接捉虫就好了,不要出现这么大的问题。
7)有些特别的对象,以前文档有调用说明,而且有特别提示,但在沿用这段代码的时候,只把代码和类说明拷贝过来,但没有把原来的特别调用提示拷贝过来,这次又犯了一个调用提示里面提示过的老错误。(好像是浪费了3个小时)。以后不同工程之间重用小段代码时候,除了代码中直接的注释外,还是要拷贝那些特别调用提示。