有些道理,大家都明白的,但真正要做的时候,却很少有人能落到实处。
在学软件工程的时候,第一次听到了单元测试和测试用例这些词,印象很深刻 。
书上讲的都是软件开发这个行业几十年来总结的经验,很有道理,也很有说服力,我也十分认同书上的做法。
我也感觉自己是一个喜欢追求完美的人,看到书上说的那些测试的方法,比如边缘测试之类的,在感叹前人总结的方法很优秀的同时,自己也暗下决心,以后我写的程序,也要有规范的接口,有明确的输入输出,要有完备的测试用例,把每一个细节都测试到,让自己的程序表现完美。
然而,在现实中,总是事与愿违。
大学期间写的程序就不说了,我到现在正式工作已经两年半了,写的代码少说也就几万行。Bug是难免的,但总是被别人发现。
我一直没有做过规范的单元测试。
原因是多方面的,但主要在自己。
懒惰,是程序员最大的敌人!
当需求明确时,我会立即投入编码,把脑子里那些自认为不错的逻辑,用程序代码实现出来,这个过程是十分开心的。程序完成后,输入预定的参数,得到预想的结果,那种成就感,难以用语言形容。
我想问一句,这个时候,这个程序算是开发完毕了吗?
以前,我是这样认为的。我也坚信,国内绝大部分的程序员,都是这样认为的。
实际上,这就好像万里长征刚迈出第一步而已。虽然有些夸张,但事实如此。
你给你的程序写出测试用例了吗?你对程序的每一个模块,做了单元测试了吗?在输入数据的时候,是否输入了边界值?是否输入了非法值?有没有试过不给输入,看看程序输出什么?
当然,那些自认为做事严谨的人,多少是会做一些测试的,这也使得他们的程序,比一般人的更稳定一些。
我想说的是,自己写的程序,定势思维会很强的,你很难想象出一些匪夷所思的参数去测试你的程序。
程序就像你的孩子,你希望他健壮,也许你会让你的孩子参加一些艰苦的锻炼,但你绝对不会拿个大铁棍砸向孩子的胳膊以检验他的骨骼是否强壮。
开个玩笑地说,拿铁棍砸别人的孩子,大多数人还是做的出来的。
我曾经自认为考虑的十分周到的程序,被人一眼就挑出一个bug,自己回去改,这个bug好了,另一个bug也随之而来,最后搞的svn被我当成磁盘一样用,改个字母都会提交一次!
话题有些远了,这篇文章的出发点,就是今天彻彻底底的进行了一次单元测试,真的是感受良多。
在做这个项目的时候,伴随着开发,我也一直在写测试用例,也一直在反复测试。我很早就知道PHP的单元测试框架,也看过很多文章,里面的很多过程和逻辑我都很清楚。可能还是因为懒吧,我只是把所有的测试用例放在一起,每次循环跑一下程序,把输出打在屏幕上,测试的时候看一眼,没什么问题就过去了。
这样很不好,还是思维定势的问题,有时候出现问题,可能就在一些细节的地方,面对满屏的输出,你是无法准确判断每个输出是否完全正确的。
后来,试着按照标准的测试框架的方式,对每一个输入,认真地写出人工判断的期望输出,然后由程序自动执行,看看是否能全部通过。
结果当然不会出乎意料,有一半的测试没有通过。
再返回头去改程序,这时才发现以前考虑逻辑的时候想法有多么简单,有那么多遗漏的地方。
你也可以邀请你的同事,鼓励他们想出各种办法来搞垮你的程序,你需要做的,就是把他们每一个稀奇古怪的输入都认真地记下来,这才是你最宝贵的财富。
我听过以前的同事讨论程序,说他新做的模块,测试了上千万的数据,一个bug都没有,但一上线,就出大问题,而且每次都这样。
另一个同事对他说,合法的输入,测试多少都没有意义,只有那些非预期的,非法的和异常的输入,才是重要的测试资源,而且,这些case都应该好好保留,以后每次测试,就从这些bad case入手。
我对这番对话记忆深刻,从那时起,我也在逐渐应用这种方式去测试我的程序。
今天,终于切身地感受到这种开发方式的好处。
我在线下修改一个bug,就可以避免上万的用户在线上碰到bug。
作为互联网产品,线上服务的稳定性绝对是第一位的!
话题基本到这里,我想再引申出另一个问题,就是关于“落实”这两个字。
现代人类文明,大概有2000年了,我们的前辈,给我们总结出了大量的经验教训,希望我们能少走弯路。
我领悟出一个道理,世上绝大部分事,都很容易做,每一份事业,都很容易成功,因为很多是前人做过的,他们总结的经验,我们很容易就能得到。
可实际情况却是,大部分人都不能把事做好,都不能做出一份成功的事业。
是他们不懂道理,没听过经验教训吗?
我想不是,原因就在于,他们没有很好地落实每一项应该完成的事。
就拿上学来说,我们都经历过至少十几年的校园生活,大部分人的学习成绩应该都不是所在学校的No.1吧?
你回想一下,那个时候的年级第一,他比你聪明吗?不见得吧。
那个时候老师都说,要好好学习,课前要预习,上课要认真听讲,课后要按时完成作业,不懂就问。很简单的道理,不是吗?我的印象中,学校里学习好的人,平时都很贪玩的。他们不比我聪明,晚上熬夜也没我时间长,他们比我学习好,只有一个原因,他们听话。他们认真地做到了老师要求的每一件事,而且一点也不难,很容易就超过了别人。
思维再跳跃一下,就说这开车吧。
不准酒后驾车,不准疲劳驾驶,交通路口要减速慢行,要与前车保持安全距离。
很简单的四条吧,大家看看新闻,哪次事故不是因为酒后驾车,超速行驶呢?出了事,轻则误事赔钱,重则车毁人亡,你说做到这几条有多难呢?还是难以落实。
再回到程序开发上,就像我遇到的问题,我们有很多开发经验,有软件工程,有测试框架,有编程习惯,有代码标准,可真正做到的有多少呢?有几项是我们真正落实的呢?
还有创业,我认为也一样。
很多成功的老总,都会总结他的经历。很多人都说,他之所以成功,就是因为坚持不懈,锲而不舍地做了一件事,把这件事认真地做好,他就成功了。
而现在的很多创业公司,拿着几千万美元的风险投资,就不知道该干嘛了,这也干,那也干,这么大的互联网,没有他不干的。讲起道理来,他比谁都能说,真正做起事来,前人总结的经验,就完全抛在脑后了。
还是一句话,落实很难。
还是收起浮躁的心,踏踏实实,脚踏实地,把最简单的事做好,每落实一件事,离成功就会更近一步,我坚信!