论坛首页 综合技术论坛

你们公司单元测试吗?

浏览 51264 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-01-15  
我看了Kent Benk的《TDD by example》以后没有多少感觉,收获不多,但是最近读了Rod Johnson的《without EJB》中单元测试那一章,却发现原来我对于单元测试竟然知道的这么少,有那么多东西需要我学习和去实践。由此也带来很多疑问,主要就是太细粒度单元测试必要性如何,如果严格走TDD,会带来什么样的体验等等问题,另外也想找时间看看spring的单元测试代码,看看Rod是怎么写的,学习学习。

最后想说的是两点:

1、单元测试本身就应该是程序代码的一部分,所谓写测试带来高成本延长工期的说法是无稽之谈,你不写单元测试只能说明你一惯偷工减料,养成了这种坏毛病,结果你就以为偷工减料是理所应当的了,而写单元测试反而是画蛇添足了。

2、编写有效的单元测试是一个非常讲究技巧的活,包含了很多很多经验和知识在里面,单元测试代码可以看出来一个程序员的水平高低。
0 请登录后投票
   发表时间:2006-01-15  
补充一点:推行TDD是一件很难的事情,或许TDD学(Art)才是程序员最重要的一课.
0 请登录后投票
   发表时间:2006-01-15  
nihongye 写道
补充一点:推行TDD是一件很难的事情.

分层多,会带来复杂度的问题底。
0 请登录后投票
   发表时间:2006-01-15  
robbin 写道
我现在觉得:如果不施行TDD,就很难写出来高质量的单元测试,似乎看起来TDD是施行有效单元测试的一个必要前提。

我随便举个例子。譬如说以前potian就讲,没有大量工厂的程序不是好程序(当然,那是在IoC容器流行之前)。后来IoC容器流行了,我说过一句“程序代码里不应该有new操作”(主要是针对带有业务逻辑的对象而言)。就有人问了,为什么一定要用创建型模式?为什么不能new UserManager()非要ManagerFactory.getUserManager()或者依赖注射?然后大家讨论来讨论去,三天讨论不出结果。

那么当你用TDD的时候怎么样?你马上就想mock UserManager,但是如果你在代码里写new UserManager()你就mock不了,你就得费老鼻子劲去写这个单元测试。所以你就改变实现方式,用一个工厂,然后先mock这个工厂。这事情很奇妙,我也说不出它理论上到底是怎么回事,但事实就是这样:紧耦合的坏设计会让你写不出单元测试,所以你就会自然而然的采用松耦合的设计——甚至你写完了还没有意识到这一点。
0 请登录后投票
   发表时间:2006-01-15  
简单地说,测试代码和产品代码,都是软件的一部分。测试代码描述你的设计、你的思路、你对产品代码的期望。“我在写这段程序的时候怎么想的”,其重要性并不亚于产品代码本身,甚至可能比后者还要重要。不写测试,就等于说你没有交付完整的软件产品。

为什么有些程序紧密耦合?因为没有人尝试测试它。为什么有人把业务逻辑写在JSP里面?因为没有人尝试测试它。为什么一个方法写出一百多行?因为没有人尝试测试它。有人说存在就是合理,业务逻辑写在JSP里面又怎样,它存在它就合理。那么好,今年西安程序员的市价2000往下,这也是存在。
0 请登录后投票
   发表时间:2006-01-16  
我想说几点
1. 没有测试用例代码不代表没有测试. 没有产出测试代码并不直接代表产品代码的质量有问题.   我们需要在合理的项目周期里制定出测试边界. 哪些必定需要写单元测试代码,哪些直接做功能测试,整合测试. 哪些不能依赖外部容器,需要自动的,重复的做回归测试. 哪些就直接扔到测试服务器上跑.  没有人否定测试的重要性,但测试的手段有很多......

2. 测试就是测试,设计就是设计. 二者的所处的层次不同.
0 请登录后投票
   发表时间:2006-01-16  
JJYAO 写道
我想说几点
1. 没有测试用例代码不代表没有测试. 没有产出测试代码并不直接代表产品代码的质量有问题.   我们需要在合理的项目周期里制定出测试边界. 哪些必定需要写单元测试代码,哪些直接做功能测试,整合测试. 哪些不能依赖外部容器,需要自动的,重复的做回归测试. 哪些就直接扔到测试服务器上跑.  没有人否定测试的重要性,但测试的手段有很多......

2. 测试就是测试,设计就是设计. 二者的所处的层次不同.

赫赫,下面说的不是特指你而已。也不是针对你的观点,仅仅是因为看到你里面几次提到的“我们的项目.."之类的词语而想到以前几个人跟我交流的观点,大多提到了这样的观点:
因为自己项目里面已经有了某种所谓自动测试框架,使得某方面效率比较高,比如系统自动帮助测试等等。。以至开始怀疑自己手工写测试的必要性。
这里不愿意扯入对于那些已经有成套测试框架的系统平台的争论,但是我个人觉得使用那些平台的开发人员不应该出来说“自己手工写测试“有没有必要的之类的言语。
这个言语至少从结论上来说不正确,因为你自己其实已经有了测试代码(系统自动测试生成部分,只是你没写而已)。 传递出来的信息等于说:测试没什么重要的,这些都可以留给别人来做,或者更高的层次来做。

如果是这个意思的话,我想追索其根本根源还是不重视测试的。
0 请登录后投票
   发表时间:2006-01-16  
单元测试是一个内涵很丰富的话题,简单想想,有如下可以讨论的话题:

1、测试驱动开发
如何有效实施测试驱动开发;测试驱动开发的模式等等,可以参考TDD by Example

2、单元测试
单元测试中使用的设计模式和有效实践

3、单元测试的工具集
Ant,Junit,mockobject,easymock,测试覆盖率工具

4、如何做集成测试

5、针对数据库应用的单元测试最佳实践
0 请登录后投票
   发表时间:2006-01-16  
刚刚看了一下Spring的jdbc和hibernate部分的testcase,果然没有使用数据库,大量运用easymock,纯粹的单元测试。

而我平时惯常使用的测试方法(即在setUp里面启动Spring容器和HSQLDB In-Memory)那根本就不叫单元测试,而应该叫做集成测试了。这种方式每个Test完成之后都必须关闭Spring容器和HSQLDB,每个Test之前都必须独立初始化数据,以保证Test之间的独立性,我早就觉得这种方式运行测试集未免太慢了点,看来是自己把集成测试当单元测试用了。

然后又看了一下Hibernate的testcase,是连接HSQLDB,每次test都重建SessionFactory去测试的,和我采用的方法大同小异。这样来看,对于我们平时使用的Hibernate/Spring/Webwork来说,单元测试方案是不是可以这样来制订:

如果业务bean基本上就是持久化逻辑,那么就应该采用像Hibernate那种方式测试,当然考虑到我们使用Spring封装了Hibernate,所以仍然要启动spring容器和HSQLDB来测试业务bean。

如果业务bean还包含商业运算逻辑,那么就应该使用DAO接口分离持久化逻辑,使用Mock对象替换DAO实现,单独测试商业运算逻辑。

对于Web Action,不应该直接使用业务bean,而应该提供Mock对象,以单独测试Action工作是否正常。
0 请登录后投票
   发表时间:2006-01-16  
robbin 写道
刚刚看了一下Spring的jdbc和hibernate部分的testcase,果然没有使用数据库,大量运用easymock,纯粹的单元测试。

而我平时惯常使用的测试方法(即在setUp里面启动Spring容器和HSQLDB In-Memory)那根本就不叫单元测试,而应该叫做集成测试了。这种方式每个Test完成之后都必须关闭Spring容器和HSQLDB,每个Test之前都必须独立初始化数据,以保证Test之间的独立性,我早就觉得这种方式运行测试集未免太慢了点,看来是自己把集成测试当单元测试用了。

然后又看了一下Hibernate的testcase,是连接HSQLDB,每次test都重建SessionFactory去测试的,和我采用的方法大同小异。这样来看,对于我们平时使用的Hibernate/Spring/Webwork来说,单元测试方案是不是可以这样来制订:

如果业务bean基本上就是持久化逻辑,那么就应该采用像Hibernate那种方式测试,当然考虑到我们使用Spring封装了Hibernate,所以仍然要启动spring容器和HSQLDB来测试业务bean。

如果业务bean还包含商业运算逻辑,那么就应该使用DAO接口分离持久化逻辑,使用Mock对象替换DAO实现,单独测试商业运算逻辑。

对于Web Action,不应该直接使用业务bean,而应该提供Mock对象,以单独测试Action工作是否正常。

在测试WEB的应用的时候,可以采用SPRING提供的org.springframework.mock包,里面提供了对ServletContext/SevletRequest/SevletResponse的MOCK,让POJO不在容器里也很容易被测试.
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics