微服务时代,单元测试不重要了吗?
很多人认为,在进行任何变更之前,最好使用端到端的「冒烟测试」来覆盖自己的应用程序。
这似乎是一个好主意。
然而,事实上,假如执行测试的位置离我们代码修改的地方越远,就越难编写出针对需要覆盖特定代码逻辑的自动化测试用例。
此时,我们经常要反复调整端到端自动化测试用例中的输入参数,并且,反复查看它的行为,才能做出真正可用的自动化测试用例。
这就像试图在飞机上,用石头击中地面的一个小目标,可能需要多试几次才行。
实际上,如果能离要修改的地方越近,测试起来就越容易。
不幸的是,很多代码都缺乏模块化,而模块化恰恰正是关键点。
作为软件设计的传统部分(类级、函数级)的模块化,今天被认为不那么重要了。
在软件开发中,「Service」是一个粒度合适的测试单元。有些时候,的确是的。「Service」的确是架构讨论和规划时用的重要单元。
然而,当我们想知道
“这段代码是如何运行的?”
“我需要再写多少行代码,才能调用它,并查看它的实际功能?”
时,我们通常希望得到的是更细粒度的「单元(Unit)」。
此时,我们可以通过自动化测试用例从外部理解代码,也可以从内部理解它,且可以将其与代码的其余部分隔离开来查看。
你可能会想,看上去好像不是这样。但是,这两件事的确是相关的。
有些人习惯于下面的工作方式:
编写出一个很大一片「单元(Unit)」代码,然后再通过自动化测试用例,来确信其运作是良好的。
这件事是一件很困难的事情。
而且,随着单元越来越大,编写自动化测试用例也就越来越困难。
所以,测试用例的便捷性可以成为一种“良好设计”的探测针:
当写自动化测试用例很痛苦的时候,我们应该看看是否要模块化,是不是模块化还不充分,看看还能做些什么来让它变得更好。
假如,我们能将测试只看作是一种工具,那么,我们就可以绕过大量关于单元测试中“什么是单元”以及“单元到底什么大小合适”的争论了。
它可以是一个类,也可以是一个函数,它可以是一个集群。
但是,它应该是一个小东西,并可以把它看作一个单元。
如果你对“单元”的感觉与你的技术提供给你的最简单的结构相一致,以实现模块化和封装,这是很好的。
我认为,「单元」是单元测试的对象——
容易的单元测试是针对某种类型的接口工作的,只覆盖少数情况,并且不会进行大量的设置以达到模糊的条件。它们记录了一个简单易懂的东西——一个单元。
如果很难为代码段编写相应的测试用例,那么,这就暗示着:你的代码还可以更加模块化,并且模块应该相对较小。
确保它们是独特的,可以理解的,它们的行为是可以发现的。
这样做也许才是加深对整个系统的理解的第一步。
通过从对各部分如何工作的理解的坚实基础上进行推理,你可以建立对整个系统的理解。
错误就是对系统误解的征兆。一旦有了良好的模块化,系统质量也会随之提高。
乔梁老师开课啦~视频课程《持续部署训练营(Python版)》, 限时特价!
你的软件开发效率够高吗?质量够好吗?你的团队多长时间才能向用户实时推送一个生产变更?你的软件在发布时,你是否因担心软件交付质量而感到压力倍增?你是否遇到过部署失败,甚至导致停机的情况?持续部署可以帮助你消除软件交付的痛苦,让你能专注于为客户高价值的需求,而不会因为这些交付执行类问题而花太多精力。本课程通过学练结合,理论结合实战,让你体验如何使用构建-测试-部署管道,进行持续部署。并练习如何在有效监控部署的同时,逐步发布功能特性,并作数据库结构变化。
(扫码订阅)