项目中单元测试容易出现的普遍问题归纳(Junit/Spring/Spring-test/Dubbo/RocketMQ/JAVA)

标签: 项目 单元测试 问题 | 发表时间:2015-08-14 20:16 | 作者:fish_no7
出处:http://www.iteye.com

   最近公司要求项目在使用maven构建的时候不能跳过test的生命周期,也就是通过mvn test命令需要将整个项目运行起来。因为之前项目组的成员都是在eclipse中去执行的unit test,在maven对所有模块构建的都是直接-Dmaven.test.skip=true的方式直接跳过UT的。
   这次刚好借这个机会把项目所有模块中的UT整理下,在整理的过程中遇到了很多的问题,这边我把几个比较严重的问题记录了下。
   先介绍下公司使用的基本中间件:DUBBO,RocketMQ,Spring。

(一) 环境问题

    1. 问题描述:由于项目中含有多个子模块,但是基础的环境比如DUBBO和RocketMQ,甚至基本的Spring启动环境都是相同的,但是目前的项目中并没有抽象出统一的启动环境,导致的问题就是每个新加入的团队成员做单元测试的时候都需要自己去了解每个中间件环境的细节,这些与业务无关的细节会严重拖累新加入成员的开发进度。最后为了赶进度,也为了减少学习的成本,后加入的成员,就直接把其他子工程的环境直接复制放入到自己的工程中来启动UT。最后导致的问题就是由于对细节的不了解,最后按了葫芦起了瓢,不仅没起到快速启动的效果,反而在解决各种启动报错的问题中耗费了时间。而由于是复制别人的环境,所以环境中启动了很多自己工程中在运行中其实不要启动的组建。最糟糕的就是复制了全环境,有时我们的单测其实只需要运行一个简单的service的某个方法的细节,最后导致启动了各种DUBBO服务,RocketMQ的服务和客户端,各种数据库连接池,扫描了所有的bean等等,最后的问题就是一个很简答的UT都启动的特别慢。

    2. 解决思路:针对项目抽象出一个单独的工程,提供给业务模块需要的时候引入。此独立的工程只需要提供基本统一的环境就,并且对外提供抽象接口供业务测试单元继承。可以借助spring-test帮你构建。

(二) DAO层数据插入问题(不能二次执行)

    1.问题描述:很多人在测试DAO层的数据插入时,简单的构造了条数据当时插入成功了,程序员觉得万事大吉了,但是他们忘了项目的UT是要经过一次次的执行的,这样当你下次重复执行的是不是就会发现数据库抛出duplicate primary key的错误。

    2. 解决思路:关于此类问题的解决方法有很多,但是一般有个原则就是单测的数据不应该污染数据库,也就是不应该持久化到数据库中的,可以使用事务控制整个UT,并在测试方法结束的时候回滚,目前Spring已经提供了此类事务的支持(有兴趣的可以看下spring的@TransactionConfiguration和@Tranactional以及AbstractTransactionalJUnit4SpringContextTests抽象类);
    就算不用事务支持的话,也应该在插入前对数据库进行一次删除操作,最起码不应该让UT二次执行的时候就会抛出错误,这是最基本的要求。

(三) 对外部依赖的问题

    1. 问题描述:现在很多工程都是基于SOA的架构设计的,各业务模块是以服务的方式对外提供服务。这样在UT的时候基本很难避免对其他业务接口的调用。大家知道测试环境那个的服务都是不稳定的,也许在你们调试的时候可用,下次执行的时候对方测试的接口不可用了,如果是基于DUBBO的服务,那么你在执行单测的时候就得眼巴巴的等到对方超时返回,或者返回不符合预期,测试不通过。

    2.解决思路:Mock 还是Mock,Mock框架的话我首选的还是Easy Mock。

(四) 数据过期超时导致的异常

    1.问题描述:严格来说这个不算问题,但是如果你向我一样,要在后期去优化整个项目的UT工程的时候你就会崩溃,最简单的场景:你要查某个时间段的数据,而且期望的是数据的条数大于0,也许当时你能测试通过,但是这个业务场景可能是依赖于时间段的,我后面来执行的时候数据过了有效期,此时UT是不能被通过的。

    2.解决思路:对可能出现数据超时的情况进行异常处理。

    以上是我在整理和重构的时候遇到的几个比较频繁和严重的问题,所以就归纳出来了。
我觉得一个合格的单元测试最起码的要求是能重复执行,并且不应该对外部的执行时有强依赖,UT只是测试项目中最小的逻辑甚至是代码单元的,所以应该小而简单。希望以后大家在构建单测的时候能够尽量避免我上面列出的几个问题,养成良好的习惯,提高单测质量!

    

已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [项目 单元测试 问题] 推荐:

项目中单元测试容易出现的普遍问题归纳(Junit/Spring/Spring-test/Dubbo/RocketMQ/JAVA)

- - 编程语言 - ITeye博客
   最近公司要求项目在使用maven构建的时候不能跳过test的生命周期,也就是通过mvn test命令需要将整个项目运行起来. 因为之前项目组的成员都是在eclipse中去执行的unit test,在maven对所有模块构建的都是直接-Dmaven.test.skip=true的方式直接跳过UT的.

单元测试实践的主要问题与解决

- - 博客 - 伯乐在线
来源: dellfox 的博客. 摘要:本文是我在“第十届中国系统与软件过程改进年会广东会场”所作演讲的整理稿,主要分享单元测试的一些要点、单元测试实践的主要问题,以及如何来解决这些问题. 单元测试,就是针对代码单元的独立测试. 代码有一个基本特性,就是对数据分类处理. 嵌套的判定,会使分类次数的翻倍.

Android单元测试

- - CSDN博客推荐文章
    单元测试不管对于初学编程还是已经工作了很久的开发者来说,都不乐意花时间去写认为没用的代码进行测试,只要交给测试人员就行了,虽然这样也能把软件改出来,但也许你要花上几倍的时间去修改问题,如果在开发的过程中花点时间去写单元测试代码,把尽可能出问题的地方都测试一遍,把问题扼杀在最开始的地方,这样你就不必为后来找问题出处而烦恼.

Hadoop之MapReduce单元测试

- - ITeye博客
通常情况下,我们需要用小数据集来单元测试我们写好的map函数和reduce函数. 而一般我们可以使用Mockito框架来模拟OutputCollector对象(Hadoop版本号小于0.20.0)和Context对象(大于等于0.20.0). 下面是一个简单的WordCount例子:(使用的是新API).

springboot单元测试技术

- - 海思
整个软件交付过程中,单元测试阶段是一个能够最早发现问题,并且可以重复回归问题的阶段,在单元测试阶段做的测试越充分,软件质量就越能得到保证. 具体的代码参照 示例项目 https://github.com/qihaiyan/springcamp/tree/master/spring-unit-test.

“单元测试要做多细?”

- - 酷壳 - CoolShell.cn
这篇文章主要来源是StackOverflow上的一个回答——“ How deep are your unit tests?”. 一个有13.8K的分的人( John Nolan)问了个关于TDD的问题,他说——. “TDD需要花时间写测试,而我们一般多少会写一些代码,而第一个测试是测试我的构造函数有没有把这个类的变量都设置对了,这会不会太过分了.

文章: Android中的单元测试

- - InfoQ cn
随着Agile的普及,以及开发人员对测试重要性的认识逐步加深,单元测试已经成了越来越多软件项目开发中不可缺少的一部分. 无论项目是不是采用TDD的形式来进行开发,单元测试都能够为项目的修改和重构提供一定的保障. 有奖参与:天翼伦敦会,上传应用,为中国队加油. QClub七月技术沙龙(太原/北京/上海/厦门/西安 7月21/28/29日 免费报名中.

迈出单元测试的第一步

- - 酷勤网-挖经验 [expanded by feedex.net]
单元测试不仅是软件行业的最佳实践,在敏捷方法的推动下,它也成为了可持续软件生产的支柱. 年度敏捷调查,70%的参与者会对他们的代码进行单元测试. 单元测试和其他敏捷实践密切相关,所以开始编写测试是组织向敏捷转型的踏脚石. 我将在本文介绍符合要求的小技巧,以及在开发周期里进行单元测试的步骤. 没有自动化,单元测试的习惯也不会持续太久.

iOS开发进阶之单元测试

- - 博客园_首页
本文侧重讲述如何在iOS程序的开发过程中使用单元测试. 使用Xcode自带的OCUnit作为测试框架. 单元测试作为敏捷开发实践的组成之一,其目的是提高软件开发的效率,维持代码的健康性. 其目标是证明软件能够正常运行,而不是发现bug(发现bug这一目的与开发成本是正相关的,虽然发现bug是保证软件质量的一种手段,但是很显然这与降低软件开发成本这一目的背道而驰).

Java 单元测试利器之 Junit

- - 博客园_首页
          因为工作和学习的需要,在代码中查错的时候,第一步就是想知道这个错误具体发生在一个位置,进行一个准确的定位. 而这个定位的工作交给谁来做了呢. 不难猜出也就是这篇博客的主题---Junit. junit是一个开源的框架,也是java这一块的测试工具之一. 想了解详细请上官网,下面用代码来跟大家解释.