单元测试

一、前言

定义:单元测试(unit testing)是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作

单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。

单元测试从长期来看,可以提高代码质量减少维护成本降低重构难度。但是从短期来看加大了工作量,对于进度紧张的项目中的开发人员来说,可能会成为不少的负担。

二、哪些代码需要写单元测试?

老板为我的代码付报酬,而不是测试,所以,我对此的价值观是——测试越少越好,少到你对你的代码质量达到了某种自信(我觉得这种的自信标准应该要高于业内的标准,当然,这种自信也可能是种自大)。如果我的编码生涯中不会犯这种典型的错误(如:在构造函数中设了个错误的值),那我就不会测试它。我倾向于去对那些有意义的错误做测试,所以,我对一些比较复杂的条件逻辑会异常地小心。当在一个团队中,我会非常小心的测试那些会让团队容易出错的代码。————StackOverflow上单元测试以及JUnit的创造者Kent Beck的回答

小结:
  1. 逻辑复杂的。
  2. 容易出错的。
  3. 不易理解的。即使是自己过段时间也会遗忘的,看不懂自己的代码,单元测试代码有助于理解代码的功能和需求
  4. 公共代码。比如自定义的所有http请求都会经过的拦截器;工具类等。
  5. 核心业务代码。一个产品里最核心最有业务价值的代码应该要有较高的单元测试覆盖率。

三、什么时候写单元测试?

写单元测试的时机不外乎三种情况:

1、在具体实现代码之前。这是测试驱动开发(TDD)所提倡的;

2、与具体实现代码同步进行。先写少量功能代码,紧接着写单元测试(重复这两个过程,直到完成功能代码开发)。其实这种方案跟第一种已经很接近,基本上功能代码开发完,单元测试也差不多完成了。

3、编写完功能代码再写单元测试。我的实践经验告诉我,事后编写的单元测试“粒度”都比较粗。对同样的功能代码,采取前两种方案的结果可能是用10个“小”的单测来覆盖,每个单测比较简单易懂,可读性可维护性都比较好(重构时单测的改动不大);而第三种方案写的单测,往往是用1个“大”的单测来覆盖,这个单测逻辑就比较复杂,因为它要测的东西很多,可读性可维护性就比较差。

建议:推荐单元测试与具体实现代码同步进行这个方案的。只有对需求有一定的理解后才能知道什么是代码的正确性,才能写出有效的单元测试来验证正确性,而能写出一些功能代码则说明对需求有一定理解了。

四、单元测试的好处?

1)让我们对自己的代码有信心

修改了代码后单测依然通过的,起码说明我们的修改没有破坏程序的正确性。这从主观上能增加我们对代码的信心。虽然单元测试通过了并不意味着程序就没有bug了,但我们也要了解到这可能不是单元测试的问题。单元测试顾名思义是测试一个”单元”,这个”单元”一般是类或方法,而不是整个系统。对整个系统的测试那是集成测试,功能测试的职责。单元测试追求的是快速反馈,频繁执行。集成测试虽然测“全局”,但成本较高,所以执行频率较少。两者使用场景不同,目的不同。

2)为代码重构保驾护航

看到代码很差劲,想重构,但又担心重构之后出问题,怎么办呢?如果有单元测试情况就不一样了,重构完代码,跑一遍单元测试,如果单元测试都通过,基本上可以保证我们的重构没有破坏原来代码逻辑的正确性。不过前提是之前的写的单元测试质量很好,覆盖率很高。当然这仅限于小范围的重构,比如重构一个类或者函数的实现,但对于大刀阔斧的重构(比如单体重构成微服务,面向库表模式重构成DDD),就不适用,那个时候要重写单元测试了。

3)快速熟悉代码

单元测试不仅起到了测试的作用,还是一种很好的“文档”,通过单元测试,我们不需要深入的阅读代码,便能知道这段代码做什么工作,有哪些特殊情况需要考虑,包含哪些业务。

参考

单元测试系列一-为什么要写单元测试,何时写,写多细

你可能感兴趣的:(Java语言,单元测试)