锁定老帖子 主题:你们公司单元测试吗?
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-01-15
我看了Kent Benk的《TDD by example》以后没有多少感觉,收获不多,但是最近读了Rod Johnson的《without EJB》中单元测试那一章,却发现原来我对于单元测试竟然知道的这么少,有那么多东西需要我学习和去实践。由此也带来很多疑问,主要就是太细粒度单元测试必要性如何,如果严格走TDD,会带来什么样的体验等等问题,另外也想找时间看看spring的单元测试代码,看看Rod是怎么写的,学习学习。
最后想说的是两点: 1、单元测试本身就应该是程序代码的一部分,所谓写测试带来高成本延长工期的说法是无稽之谈,你不写单元测试只能说明你一惯偷工减料,养成了这种坏毛病,结果你就以为偷工减料是理所应当的了,而写单元测试反而是画蛇添足了。 2、编写有效的单元测试是一个非常讲究技巧的活,包含了很多很多经验和知识在里面,单元测试代码可以看出来一个程序员的水平高低。 |
|
返回顶楼 | |
发表时间:2006-01-15
补充一点:推行TDD是一件很难的事情,或许TDD学(Art)才是程序员最重要的一课.
|
|
返回顶楼 | |
发表时间:2006-01-15
nihongye 写道 补充一点:推行TDD是一件很难的事情.
分层多,会带来复杂度的问题底。 ![]() |
|
返回顶楼 | |
发表时间:2006-01-15
robbin 写道 我现在觉得:如果不施行TDD,就很难写出来高质量的单元测试,似乎看起来TDD是施行有效单元测试的一个必要前提。
我随便举个例子。譬如说以前potian就讲,没有大量工厂的程序不是好程序(当然,那是在IoC容器流行之前)。后来IoC容器流行了,我说过一句“程序代码里不应该有new操作”(主要是针对带有业务逻辑的对象而言)。就有人问了,为什么一定要用创建型模式?为什么不能new UserManager()非要ManagerFactory.getUserManager()或者依赖注射?然后大家讨论来讨论去,三天讨论不出结果。 那么当你用TDD的时候怎么样?你马上就想mock UserManager,但是如果你在代码里写new UserManager()你就mock不了,你就得费老鼻子劲去写这个单元测试。所以你就改变实现方式,用一个工厂,然后先mock这个工厂。这事情很奇妙,我也说不出它理论上到底是怎么回事,但事实就是这样:紧耦合的坏设计会让你写不出单元测试,所以你就会自然而然的采用松耦合的设计——甚至你写完了还没有意识到这一点。 |
|
返回顶楼 | |
发表时间:2006-01-15
简单地说,测试代码和产品代码,都是软件的一部分。测试代码描述你的设计、你的思路、你对产品代码的期望。“我在写这段程序的时候怎么想的”,其重要性并不亚于产品代码本身,甚至可能比后者还要重要。不写测试,就等于说你没有交付完整的软件产品。
为什么有些程序紧密耦合?因为没有人尝试测试它。为什么有人把业务逻辑写在JSP里面?因为没有人尝试测试它。为什么一个方法写出一百多行?因为没有人尝试测试它。有人说存在就是合理,业务逻辑写在JSP里面又怎样,它存在它就合理。那么好,今年西安程序员的市价2000往下,这也是存在。 |
|
返回顶楼 | |
发表时间:2006-01-16
我想说几点
1. 没有测试用例代码不代表没有测试. 没有产出测试代码并不直接代表产品代码的质量有问题. 我们需要在合理的项目周期里制定出测试边界. 哪些必定需要写单元测试代码,哪些直接做功能测试,整合测试. 哪些不能依赖外部容器,需要自动的,重复的做回归测试. 哪些就直接扔到测试服务器上跑. 没有人否定测试的重要性,但测试的手段有很多...... 2. 测试就是测试,设计就是设计. 二者的所处的层次不同. |
|
返回顶楼 | |
发表时间:2006-01-16
JJYAO 写道 我想说几点
1. 没有测试用例代码不代表没有测试. 没有产出测试代码并不直接代表产品代码的质量有问题. 我们需要在合理的项目周期里制定出测试边界. 哪些必定需要写单元测试代码,哪些直接做功能测试,整合测试. 哪些不能依赖外部容器,需要自动的,重复的做回归测试. 哪些就直接扔到测试服务器上跑. 没有人否定测试的重要性,但测试的手段有很多...... 2. 测试就是测试,设计就是设计. 二者的所处的层次不同. 赫赫,下面说的不是特指你而已。也不是针对你的观点,仅仅是因为看到你里面几次提到的“我们的项目.."之类的词语而想到以前几个人跟我交流的观点,大多提到了这样的观点: 因为自己项目里面已经有了某种所谓自动测试框架,使得某方面效率比较高,比如系统自动帮助测试等等。。以至开始怀疑自己手工写测试的必要性。 这里不愿意扯入对于那些已经有成套测试框架的系统平台的争论,但是我个人觉得使用那些平台的开发人员不应该出来说“自己手工写测试“有没有必要的之类的言语。 这个言语至少从结论上来说不正确,因为你自己其实已经有了测试代码(系统自动测试生成部分,只是你没写而已)。 传递出来的信息等于说:测试没什么重要的,这些都可以留给别人来做,或者更高的层次来做。 如果是这个意思的话,我想追索其根本根源还是不重视测试的。 |
|
返回顶楼 | |
发表时间:2006-01-16
单元测试是一个内涵很丰富的话题,简单想想,有如下可以讨论的话题:
1、测试驱动开发 如何有效实施测试驱动开发;测试驱动开发的模式等等,可以参考TDD by Example 2、单元测试 单元测试中使用的设计模式和有效实践 3、单元测试的工具集 Ant,Junit,mockobject,easymock,测试覆盖率工具 4、如何做集成测试 5、针对数据库应用的单元测试最佳实践 |
|
返回顶楼 | |
发表时间: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工作是否正常。 |
|
返回顶楼 | |
发表时间: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不在容器里也很容易被测试. |
|
返回顶楼 | |