子在川上曰

    逝者如斯夫不舍昼夜
随笔 - 109, 文章 - 0, 评论 - 837, 引用 - 0
数据加载中……

关于单元测试的讨论

今天收到javaeye的一个有回复通告的邮件,一查原来是一个很久以前的帖子又人回复了。帖子原地址如下:http://forum.javaeye.com/viewtopic.php?p=110113#110113 
 
-------下面的是顶帖:---------------
当项目进展到一定程度,也会产生出大量的单元测试代码。而且这些单元测试代码也被不断的增加、修改和删除。渐渐单元测试代码也变得难以维护了,里边夹杂了太多的业务逻辑。创建一个新的测试要做很多初始化的工作,很难在ide里直接运行所有测试,很难单独运行某项测试,运行所有的单元测试要比较长的时间......

我想了下,造成这种现象的原因有以下几种:
1.未及时对单元测试进行重构,删除不必要的测试,合并类似的测试。
2.单元测试粒度过大,造成测试类过于臃肿。应该把大粒度的测试抽出来单独作为功能测试运行。
3.大量依赖外界环境,如数据库。应使用mock object解除依赖关系。
 
-----我对此帖的一点看法:--------------
这个帖的楼主对单元测试显示理解有偏颇。
 
(1)“里边夹杂了太多的业务逻辑”,单元测试怎么能夹杂业务逻辑呢?!!!单元测试代码是用来测试业务逻辑的,楼主怎么还加入什么业务逻辑。单元测试应该尽量的简单和独立,简单性和独立性是单元测试代码的原则。细粒度是实现单元测试代码简单性和独立性的方法。
 
单元测试的目的是为了让我们今后维护时能更快的定位BUG,所以简单独立测试代码更易读、更利于这个目的。如果阅读一个单元测试代码要超过十分钟,我觉得这个单元测试就算是失败的。
 
(2)“创建一个新的测试要做很多初始化的工作”,其根本原因是在于楼主的单元测试做法有误,"单元测试粒度过大,造成测试类过于臃肿",“大量依赖外界环境,如数据库”。
千万不要写类似这样的单元测试代码:[输入一个数据,然后数据经过业务逻辑处理,而经过Hibernate进入数据库,然后单元测试从数据库读出数据来看看数据是否正确],这样的写单元测试的思路是根本错误的。试想,如果运行测试时出错,你就很难从如此庞大混杂的代码中定位问题是出在业务逻辑层面、还是中间层、还是数据存储层。
 
千万不要写上面那种一杆子捅到底的测试代码。你应该这样,针对[数据经过业务逻辑的处理]来写一个单元测试。只针对最复杂和最核心的逻辑来写单元测试,减少了单元测试代码的数量,也就减少了对测试代码本身的维护量。有一些不应该由单元测试来做的工作,还是留到集成测试和测试员的beta版测试吧。
 
(3)单元测试要尽量做到环境无关性。比如测试EJB的单元测试,运行它并不需要启动Weblogic等EJB容器才能测试的,因为我们主要是测试它的业务逻辑,业务逻辑和weblogic容器是无关的。要实现这个目的,也就要求我们在写代码时要把业务逻辑写得更单纯,让它和容器相关的代码分离开来。
 
数据库也是一个常见的环境无关性问题,我们必须让单元测试脱离数据库(也就是脱离环境)而能运行。解决的方法是:我们可以写一个假(mock)的数据库,这是很简单的:一个类加几个List变量就可以模拟库和表了。
 
 
-----------另一个帖子回道: -----------------------
小规模的项目和试验性项目才可能搞搞这么频繁的单元测试,大的项目从项目规模,时间上都不太现实
 
-----------我的看法和回复: -----------------------
如果你维护过大项目,你就不会说这样的话了。
(1)没有单元测试,你无法重构,因为你不知道你的修改是否正确。
(2)没有单元测试,你出错后,你无法最快的定位BUG所在。并且在修改BUG后,你无法得知自己的修改是否影响到了其他模块。
(3)没有单元测试,你很难进行需求的修改。
总之一句话:没有单元测试,就很难对代码做修改。所以说小项目可以没有单元测试代码,但大项目一定要有,不然没法维护。另外,单元测试代码逻辑简单,写起来并不是想想中的那样耗时。

posted on 2006-03-07 14:34 陈刚 阅读(369) 评论(0)  编辑  收藏 所属分类: Test




标题  
姓名  
主页
验证码 *  
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2006-04-24 18:33 编辑过
 
 
相关链接:
网站导航: