所有代码都需要单元测试覆盖吗?
作者:网络转载 发布时间:[ 2014/4/1 11:29:35 ] 推荐标签:单元测试 覆盖率

unit-test-quadrants
图中,产品代码可以分为四个类别,纵轴是从单元测试中得到的收益,横轴是单元测试的成本,我们从投入产出的角度来分析,到底哪些代码适合于进行单元测试:
琐碎且无甚依赖的代码。比如getter/setter, 比如简单地调用系统时间,比如 toString()等等,基本是不需要测试的。虽然测起来容易,但我们有信心说它们出错的概率也非常低,测这种代码的确索然无味。
承上启下的代码。比如用MVC框架实现的代码里,某些service层只是简单地被Action层调用,然后转发到下一层去。这种粘合代码不具备太多被测试的价值,而且由于是衔接上下两层的传话筒,测起来却需要对周围各层进行mock或打桩。要想验证其所做的那一点点工作,其实还挺麻烦的。当然,也有一些观点比如”London School TDD”坚持认为,对于企业级应用,要像制作香肠一样,一层一层地对交互(interaction-based)进行测试,每测一层都需要mock的帮助。
具有算法和业务逻辑的代码。比如排序或处理数据等代码,这些是值得进行单元测试的代码了。虽然有一定的成本,但是由于算法逻辑的输入输出非常确定,结构复杂且具有业务价值,外部依赖较少,在这上面投入是一定可以得到丰厚回报的。这即是”Classic TDD”观点,对状态进行测试(state-based)。
过于复杂的代码。充满复杂逻辑、交织在一起、散发着各种坏味道的遗留代码,像一座未开发的金矿,你需要做很多清理工作,才能顺利地进行开采,否则将寸步难行,不知从何下手,而且成本极高。这种代码建议先进行粗粒度重构和接口测试(孰先孰后要根据实际情况),破除掉严重的依赖,找到所谓的接缝(Seam),将具有逻辑的部分与承上启下的代码分离开,然后立即将单元测试注入到接缝中,形成对有逻辑代码的保护网,随后继续缩小重构的范围,不断地添加测试和重构,逐渐渗透形成一张网,将又臭又硬的代码块切碎。
除了3)以外的代码怎么测?可以采用其他测试手段,比如功能性测试来进行粗粒度覆盖,同样能提升对产品的信心,并且成本更低,特别适合敏捷迭代式开发,能够在有限的时间盒内达到预期的质量水平。
此外,持续地重构代码,同时编写更有效的单元测试,也是敏捷开发者应该具备的基本功,有助于提高投入产出比。

sales@spasvo.com