下午写代码,一边写单元测试,一边修复通过单元测试发现的问题,远比用debug调试效率更高,且会发现一些自己都意想不到的问题。所以,今天想和大家聊聊“单元测试”:
“这个方法逻辑这么简单,一眼就能看明白,还需要写测试么?”
这个是我们在代码走查过程中,大家最喜欢说的一句话,听起来似乎很有道理。但这个“有道理”有一个前提,是我们在静态的看待这个代码,和静态的看写代码这件事情,而这两个前提其实是不成立的:
复杂系统的烂代码,不是一天两天产生的,需求变更是很经常的事情,我们的代码一开始可能都很简单,但日积月累,就变得很复杂了,今天的简单并不代表一直都简单,而如果一开始就不去写,后面变更的复杂的时候,基本上也不会愿意去写。
写单元测试,本身这个技能不是静态的,很多时候大家不愿意写,是因为交付压力太大,觉得写单元测试很花时间,不好的单元测试维护成本也高,这是一个恶性的循环。里面蕴含了两个问题,写单元测试花时间,是因为你对这件事情的熟练程度不够高,不好维护的单元测试源于你写法有问题,甚至可能是代码结构不好,这说明问题不在于“单元测试不好”,问题在于你对这个技能的掌握不够。所以,当我们面临一些复杂的场景问题的时候就更写不出来了。
因此,如果我们换个角度来看待这个问题,一个简单的逻辑,去写单元测试相对来说更容易,便于我们修炼写的技能,当代码演变更复杂的时候,相应的测试也会更加的丰富起来。久而久之,大家会养成一个习惯,当写的越多,自然会写的越快,也会写的越好,技能提升了,当我们面临复杂场景的时候也有了更大的信心。而且,一开始就写测试的话,自然会从业务上去考虑边界和异常场景的处理策略。习惯本身的力量是一个长期的累计效应,比做当下这件事情更有价值。
再从另外一个层面来看待这个问题,我们讲到在梳理需求用例的时候,需要考虑这个需求的测试策略,哪些用例是可以通过UT覆盖的,哪些用例是通过手工测试覆盖的,不同层级的用例互补,尤其是对于一些边界和异常的考虑。在手工测试层去做这样的测试大多是很费时费力的,而且很多有可能基本没法做。所以,当我们做故障复盘的时候会看到很多边界和异常处理类的问题。当考虑到团队整体的质量保障测试成本后,会发现很多时候,UT的成本相对低很多。
所以写单元测试这件事情,并不单单只是对当前这几行代码的正确性的一个保障这么简单。
最后一个角度,谈谈最近和高老师结对竞赛的代码,他主要负责实现功能,我负责重构。迭代过程中,他会不断丰富功能和用例,我根据当前代码不停去做重构,因为有单元测试的保证,所以重构过程也是一个很美好的体验,可以随意尝试发挥,只要测试能跑过,重构的过程就是安全的。这和我们工程中复杂的,没有任何单元测试保证的开发代码重构相比感受就很明显。这也是为什么大家在实际项目中很难去做大的重构的原因。因为《重构》《clean code》《单元测试》这些技术实践从来都不是单独生效的,需要很好的配合起来才能达到事半功倍的效果。
下午回来,妈妈正在包抄手,一边包一边告诉我:“等我们吃完,再包饺子”,我说:“已经有抄手了,为什么还要包饺子?”。她说:“因为抄手不好带到公司去吃,饺子比较好带”。原来,她是考虑到老公明天中午带饭的问题,如此用心,满满的感动,感谢妈妈不辞辛苦每天用心为一家人准备美食。
下午吃完饭,和爸爸妈妈带筱晓去公园散步,遇见小区里的白玉兰花,开得正好,而且是罕见的淡黄色,远远看去,亭亭玉立,甚是端庄优雅,让人心生欢喜。公园里,紫荆花、海棠花、樱花也开得正盛,一串串,一簇簇,带给我们很美的感受。
在公园逛的时候,我和爸爸推车走在前面,妈妈抱着筱晓半天没跟上来。我停下来,等一等,等妈妈走上来后,我问她是不是抱不动了?她告诉我,她是在慢慢走,让筱晓看看一路上的小狗和树上的小鸟,她每天抱筱晓在公园玩的时候,都会慢慢的,走走停停,让她去看看这些新鲜东西。我不仅反思,我带筱晓出去的时候,心态远没有妈妈那么好,我更把带她出去看成了是完成一件事情,会关注从哪里出发,走到哪里然后再回家,而没有想着把步子慢下来,和她一起去观察和体验身边的美好,心态会对我们产生如此大的影响,感恩妈妈,为我做了一个很好的榜样,每天带给筱晓很丰富的体验。