【Java程序员修炼之道 之 单元测试】

单元测试是一个非常好用的工具,是一个Java程序员修养的一部分。从04年开始,我就开始在项目实践中使用单元测试。十几年来,参与的项目基本上都或多或少的使用了单元测试,多的能有100%覆盖率的要求,少的也要覆盖主要代码,发现这个实践在提高软件质量和开发速度上还是很有好处的。在和朋友同事的交流中,发现有很多项目没有使用单元测试,也有很多程序员不会写单元测试,但是大家对这个都很有兴趣。所以我想把自己掌握的关于单元测试的技能(架构、设计和技术)和实施策略分享一下。当然,要是有那个企业愿意要求我去做相关的内训和咨询,我会很高兴的。

单元测试这系列想讲讲两方面内容: 
1. 如何项目中使用单元测试 
2. Java单元测试的技术 
3. 一些实施单元测试的误区

本文包括下面几部分的内容 
1. 我所理解的单元测试的定义和分类 
2. 实施单元测试的好处 
3. Java程序员单元测试工具库

单元测试的定义和分类

单元测试的定义指程序员编写的用于测试逻辑代码的代码。我的理解中单元测试分成以下两类:

代码测试

代码测试是指对代码的实现进行测试,不依赖于第三方环境,运行速度很快。举几个例子:

  • 测试aController对象的doGet方法正确的把参数P1和P2传递给了bService对象的query方法

  • 测试一个Dao类的get方法正确的把"select a,b from t where l=5"传递给jdbcTemplate的query方法,并把查询结果返回。

集成测试

集成测试是指集成了第三方依赖之后的测试。它会依赖于第三方环境,运行速度相对代码测试慢。举几个例子:

  • 通过Http协议测试REST服务

  • 调用Dao类,测试它从数据库里面正确的获取到了数据

实施单元测试的好处进行早期测试

在软件工程中,大家都知道越早开始测试越好,越早开始测试就能越早发现缺陷,修改代价就越小。 
但是对于软件系统的测试需要你至少编写完一个可运行的最小化系统之后才能进行。在外人看到的可操作的界面出现之前,已经是开发人员好几天努力工作的汗水了。但是按照传统的工作方法,所有的这些努力,在界面没有出来之前,除了知道他们是可以编译通过的,无法进行任何测试。更甚的是,如果你的系统依赖于一个未实现的第三方系统,那么在那个第三方系统能正确响应你的请求之前,你的代码得不到任何有效的测试。 
但是使用单元测试技术,通过使用Stub和Mock技术,我们可以不用依赖界面,不用依赖第三方系统,就可以对代码进行测试处,甚至,你可以实现一个方法就测试一个方法,不用等整个功能都完成了再测试。

可以放心的修改代码以及进行代码重构

单元测试是可以自动化运行的,如果代码有良好的单元测试覆盖,在对代码进行重构和修改之后,我们可以用极短的时间(几分钟)对整个系统进行一下测试,测试全部通过,这个说明的修改对系统没有造成严重影响(这不能说明单元测试覆盖不到的地方也没有问题),于是你就可以安心的继续修改代码和重构代码。

有助于提高代码质量和架构设计

为了便于单元测试和代码覆盖,架构必然会在逻辑封装,解耦合,依赖注入,控制反转,对外接口封装等方面进行优化。 
举几个例子:

  • 把逻辑代码和界面代码都写在一起,会导致对逻辑代码的测试要包括对界面元素的解析。于是,“逻辑代码和界面代码的分离”成了停止单元测试之外的最小代价的解决方案

  • 在代码中实例化所依赖的对象,会加大隔离测试的难度,并且在所依赖的对象实现之前,无法进行测试。于是,依赖注入成了最佳的选择。

可重复对代码进行验证

编写良好的单元测试代码可以自动化运行,可以在所有的开发人员的环境里运行,可以在持续集成环境里运行,可以在每次代码修改提交后运行,项目的代码和功能在反复的收到测试。

加快开发速度

前期的小小投入,能够在整个项目周期中发挥作用,能够提高代码的质量,能够对代码进行早期测试,能够减少代码Bug,能够保证代码不会被其他代码破坏。修改Bug和调试的时间、相关的沟通时间被大幅度的减少。项目时间能更有保证。

起到代码文档的作用

对于一个方法或者一个对象的使用,有的时候光用注释很难说清楚。单元测试中对该方法/对象的使用提供了实例说明的作用,使我们更容易理解对其的使用。

Java程序员单元测试工具库

写单元测试也是需要掌握一些工具的,不过这些工具使用起来都比较简单,也和容易学习。在后面的文章中,我将会介绍其中的一部分我经常用到的。

单元测试框架

在Java世界中,有两个使用最多的单元测试框架,JUnit和TestNG。使用最多和支持最广泛的是JUnit。后面的文章中我将会给大家介绍一下它的使用。

Mock工具

Mock工具是进行代码测试所必须掌握的一个工具。目前流行的有Mockito, EasyMock和JMock这三种。我以前用过EasyMock和JMock,后来开始使用Mockito之后就停不下来了。后面的文章中会给大家介绍一下它的用法。

其他工具

通用型的我将会介绍Hamcrest,一个用于验证测试结果工具库。其他的有一些用于各种专门目的而使用的工具,这类工具有很多,比如

  • Spring Test,用于对Spring程序进行集成测试的必需品,我将会在后面的文章中介绍

  • Spring MVC Test Framework,一个用于Spring MVC编写的Web应用的工具,我将会在后面的文章中介绍

  • DBUnit,这个也有很多人用,但是我基本上没用过,所以就不介绍了。有兴趣的可以自己去看看。

  • rest-assured, Java DSL for easy testing of REST services,看起来很美,还没有用过,等我学习使用完觉得好用了再分享。



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。