为什么说几乎没有组织能正确使用TDD?

7天训练营 | 229元手把手带你掌握TDD开发
2024年4月8日
求职必备!在国外被下载27000+次的Scrum Master面试指南
2024年4月16日

绝大部分公司没有正确使用TDD

从我的面试经历来看,或许是我见过的优秀公司还不够多,几乎没有公司能正确使用TDD的。

首先绝大部分公司都没有做单元测试,原因几乎众口一词是没有时间,我们很忙,似乎是测试驱动开发是个浪费时间的工作。

诚然,在写代码的时候,需要额外写一堆测试代码,这当然需要时间。但这边你不写测试代码省下的时间,会在你集成测试的时候加倍偿还。就好比你现在要出去跑步,你说换个跑鞋太浪费时间,决定穿拖鞋去跑?

一些做了单元测试的公司,是把单元测试用来做类似协议测试的作用。比如测试的时候并不隔离数据库访问,而是需要在数据中伪造数据。这样的单元测试不具备可重复性,往往测试一次验证完功能后即成为废代码。

由于Maven等工具在编译的时候缺省自动跑单元测试,为了避免出错在持续集成环境还需要手工Skip单元测试。这样的单元测试也起不到多大作用。

单元测试应该怎么做

那么究竟单元测试应该怎么做?应该测试哪些东西呢?

首先单元测试应该是测试业务逻辑。业务逻辑是我们用来实现我们业务的东西,包括业务实体、业务用例。而这部分,严格来说来是和数据库、协议不相关的。数据库只是我们为了实现对业务实体的持久性存储而采用的工具,这个工具可以根据需要随时替换。

而数据库的正确性不是我们要测试的,这个由数据库厂商保证。因此我们的单元测试,应该不依赖数据库,因此也不需要启动数据库。有些为了能快速测试,在单元测试的时候启动内存数据库,我觉得这个是点错了科技树,跑偏了。

其次单元测试是每次测试尽量小的一个单元,往往是一个业务用例中的某个特性。比如一个单元测试方法,测试的可能是新增用户这个用例中手机号码为空的情况。

当你一个单元测试很难写的时候,往往要反思一下:我的这个单元(方法)是不是违反了单一职责原则,实现了太多的东西?一个方法可能有多个业务分叉,这时候我们需要写多个测试方法,对各个业务分叉分别进行测试。

然后要注意测试代码的质量。比如可以把测试某一个用例的放一个测试类,每个测试方法命名都考虑测试目的,比如testCreatUser_mobile_is_null这样,一眼就能看出你的测试目的。

测试代码也要具有可读性、高聚合性,符合DRY原则,否则测试代码如果不可维护,久而久之也就容易被荒废。

弄清了要测试什么,那么我们的测试方法就很清楚了。为了测试业务用例,我们需要用Mock来模拟数据库访问接口(如果有的话),然后对测试用例的逻辑进行测试,保证100%代码覆盖。在Java可以用Junit配合Mockito来实现,使用coverage来查看代码覆盖程度。

在DDD的开发中,由于业务领域、业务实体都集中在Domain层,因此单元测试变得更加清晰:只要在Domain层进行单元测试即可,并且要保证100%的覆盖率。因此,有了DDD,TDD变得更加容易、更加明确。

拨打免费咨询电话 021-63809913