- 其实换一个思路,他们只需要花几分钟的时间,就可以用人工的方式观察到很多深入的问题。过分的重视测试自动化的原因,往往在于一个不切实际的假设,他们假设错误会频繁的再次发生,所以自动化了可以省下人的力气。但是其实,一旦一个 bug 被修好,它反复出现的机会不会很大的。过分的要求测试自动化,不但延缓了工程进度,让程序员恼火,效率低下,而且失去了人工测试的精确性。
- 避免写太长,太耗时的测试。很多人写测试,叽里呱啦很长一串,到后来再看的时候,他已经不记得自己当时想测什么了。有些人本来用很小的输入就可以测试到需要的性质,他却总喜欢给一个很大的输入,下意识的以为这样更加靠谱,结果这测试每次都会消耗大量的 build 时间,而其实达到的效果跟很小的输入没有任何区别。
- 一个测试只测试一个方面,避免重复测试。有些人一个测试测很多内容,结果每次那个测试失败,都搞不清楚到底是哪个部件出了问题。有些人为了“放心”,喜欢在多个测试里面“附带”测某些他认为相关的部件,结果每次那个部件出问题,就发现好多个测试失败。如果一个测试只测一个方面,不重复测同一个部件,那么你就可以很快的根据失败的测试,发现出问题的部件和位置。
- 避免通过比较字符串来进行测试。很多人写测试的时候,喜欢通过打印出一些东西,然后使用字符串比较的方式来决定输出是否符合要求。一个常见的做法是把输出打印成格式化的 JSON,然后对比两个文本。甚至有人 JSON 都不用,直接就比较 printf 输出的结果。这种测试是非常脆弱的。因为字符串输出的格式往往会发生微小的变化,比如有人在里面加了一个空格之类的。把这种字符串作为标准输出,进行字符串比较,很容易因为微小的改动而使大量测试失败,导致很多的测试需要做不必要的修改。正确的做法,应该是进行结构化的比较,如果你要把标准结果存成 JSON,那么你应该先 parse 出 JSON 所表示的对象,然后再进行结构化的对比。PySonar2 的测试就是这样的做法,所以相当的稳定。
- “测试能帮助后来人”的误区。每当指出测试教条主义的错误,就会有人出来说:“测试不是为了你自己,而是为了你走了以后,以后进来的人不犯错误。” 首先,这种人根本没有看清楚我在说什么,因为我从来没有反对过合理的测试。其次,这种“测试能帮助后来人”,其实是没有经过实践检验,站不住脚的说法。如果你的代码写得很乱,就算你测试再多,后来人也无法理解,反倒被莫名其妙的测试失败给弄得更糊涂,不知道是自己错了还是测试错了。我已经说过了,测试不能完全保证代码不被改错,实际上它们防止代码被改错的作用是非常弱的。无论如何,后来人都必须理解原来的代码的逻辑,知道它在做什么,否则他们不可能做出正确的修改,就算你有再严密的测试也一样。
这种怕人突然走了,代码无法维护的想法,导致了一些人对测试过分的重视,但测试却不能解决这种问题。相反,如果测试太繁琐,做不必要的测试,反而容易让员工不满,容易走人,去加入在这方面更加有见地的公司。有些公司以为有了测试,就可以随便打发人走,这种想法是大错特错的。你需要明白的一个事情是,代码永远是属于写出它的那个人的,就算有测试也一样。如果核心人物真的走了,就算你有再多的测试也没用的,所以解决的方法就是把他们留住!一个有远见的公司总是通过其他的手段解决这个问题,比如优待和尊重员工,创造良好的氛围,使得他们没那么快想走。另外,公司必须注意知识的传承,防止某些代码只有一个人理解。