如何写好单元测试
本文主要阐述单元测试(UT)的重要性,以及解释一些常见的困惑,以帮助我们写出质量更高的 UT。至于类似 Mocha 怎么用,断言库怎么用之类的问题,建议看官方文档。
一、为什么需要写 UT
我发现很多朋友意识不到单元测试的重要性。在谈如何写好 UT 之前,我想先说说测试的必要性,这有利于提高我们写 UT 的内驱力。
假如,张三负责开发接口,李四负责开发具体的业务。李四会调用张三开发的接口,但由于种种原因,张三开发的接口可能存在一些 bug 。
在没有单元测试的情况下,这些 bug 往往都是由接口的使用者也就是李四发现。这无形中给李四增加了额外的工作量,因为保证接口质量的工作本该是写接口的人也就是张三应该做的事儿。假设张三还是一个比较粗心的人,其中额外增加的时间成本会更大(实际开发中经常遇到)。
张三可能会很委屈的说:谁能保证代码永远不会产生 bug 。
是的,没人能够绝对的保证代码的正确性。但张三需要对他所提供的这些接口有一些起码的保证。他需要保证这些接口的确具备接口文档中所描述的那些功能,且能正常执行。
于是乎,张三含情脉脉的望着李四的眼睛说道:I promise.
哈哈哈,显然,口头上的保证永远都是不靠谱的,我们需要白纸黑字的保证,也就是我们本文的主题:单元测试。
再回到上述的场景。假如张三为他所写的那些接口写了一些质量还不错的测试用例。
李四可能会兴奋的把张三公主抱了起来。
哈哈哈哈,原因如下:
原因一:李四不用担心接口存在一些简单 bug 。要知道因为这些简单的 bug ,李四需要向张三反馈,然后等待张三修改,张三很有可能还不会马上去修改它,李四只能等着做其他的事儿,等到张三说修好了之后,李四才能继续原先的开发。天呐,这是多么大的时间成本啊。
原因二:李四可以通过测试用例了解接口的用法。在实际的开发中,接口文档可能并没有很高的实时性,很多小的公司甚至没有接口文档这一说。在这种情况下,接口的用法以及涉及到的数据结构就只能靠张三和李四的沟通了。然而,在写了 UT 之后,这部分的沟通成本很大程度上是可以避免的。因为李四通过阅读各个测试用例可以清晰的知道接口该如何使用以及能得到怎么的结果。当然,前提是张三的 UT 写的足够好。
OK,我们再换一种场景。假如张三现在是某个开源库的作者,李四是这个开源库的使用者,两人相互并不认识。可以想象,一旦李四遇到什么 bug,他和张三的沟通成本无疑会更大。这就是为什么社区总是强调开源项目的测试覆盖率的原因。
小结一下,写单元测试有如下几点好处:
对代码有白纸黑字的保证,避免了一些或是粗心或是难以察觉的 bug 。
优秀的 UT 可以充当接口文档的作用,减少许多不必要的沟通成本。
此外还有一些好处在上述的例子中并未体现出来,在此不再赘述,各位自行感受:
方便代码的重构。
设计代码的思路更加清晰。
二、一些关于 UT 的困惑
通过跟身边同事的交流以及些许切身的感受,我总结了如下几个常见的关于 UT 的困惑。