锁定老帖子 主题:当单元测试遇到框架
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-10-05
下面我按照我们的分层架构来说说我们的分层测试,看到这里也有讨论DAO测试的,讨论分层测试的,不过很多帖子都已经不能回复了。 为什么要写这篇文章 想总结一下我们的TDD作法。正在看《JUnit in Action》,从中得到了不少经验和做事情的正确方法,并不断地修正了自己的一些错误的做法。某些问题我想知道大家的解决方案,看看大家有什么好的或者成熟的方案。 领域层 起初我们使用TDD的时候,从领域模型开始,两个人先在纸上画出领域模型的草图,写上一些显而易见的方法,然后打开Eclipse开始写JUnit单元测试,Eclipse对于TDD的支持很好,我们按照特性描述(就算是User Story吧),开始创建每个对象,当然会抱错,然后使用Eclipse自动创建那个类,我们会根据需求加入责任,然后自动生成method stub。我们花了两个小时创建了6个对象,完成了一个特性。当然,对于领域层的测试,这一切都很正常。 然后我们引入了Springframework,我们先设计一些接口,然后在Spring的配置文件中映射好实现这些接口的对象,然后我们在测试用例中写上spring初始化bean的代码:
java 代码
我们在每一个测试方法里都写,后来知道应该把这样的代码放到setUp中。我又开始使用Spring的测试框架,但是这样运行单元测试实在是太慢了!后来,知道了测试领域层的时候不要混入框架,创建对象直接用new就好。 表现层 我来继续观察表现层,其中包括Struts Action作为控制器的控制层,和Ext+HTML的UI。UI已经是一个独立的“系统”了,唯一和它联系的就是Action了。Action的作用是接收Http Request,读取参数,调用业务门面,拼接并返回Ext需要读取的数据源(XML或JSon)。我们采取的Struts和Spring的整合策略是将Action托管给Spring。这样,如果想要测试Action: 1、和Spring框架一起来测试 2、Action中的逻辑很简单,(其实Facade中封装了领域对象的协作,也可看作一种控制器)测试的目的是: 1)看看参数传过来没有 2)领域模型是不是返回了正确的值 3)XML或JSon的返回串拼接的是否正确。 4)还有更基础的是测试一下Struts和Spring的配置文件写的对不对。 3、实际上返回的领域对象只是Mock Object。 我们的测试很原始,还没有使用过StrutsActionTest这样的框架,只是直接使用Tomcat来测试(不过已经比直接使用WebLogic容易多了)。 速度很慢,每次都要初始化那些XML配置文件,而且还要读根本用不上的Hibernate的配置文件。 关于Hibernate配置文件的问题是这样的:
xml 代码
我们不得不在进行DAO测试时,使用没有注释掉的value来读取cfg.xml。而在测试Action时,又需要使用注释掉的配置。 我觉得或许采用下面的策略能好些,不过不知道各位在自己的项目中都是如何做的: 测试表现层时用专为测试这一层的Spring配置文件(我们采用了org.springframework.web.context.ContextLoaderListener这种方式),避免和Hibernate配置文件挂上联系。
持久层 采用DAO模式,我们的DAO很简单,就是直接调用Spring的getHibernateTemplate的方法,于是测试的时候关键就是测试: 1、HQL语句是否书写正确,SQL语句是否生成正确 2、Hibernate映射是否写的正确 3、Sping和Hibernate基础设施是否配置正确 4、是否按照预期完成CRUD操作。 测试一个DAO需要耗时2秒,而不是0.12秒。不过如果基于上面的目的进行测试也无可厚非。
单元测试真的是这样做的吗? 按《JUnit in Action》上的说法,单元测试还包括集成单元测试,功能单元测试。 所以看上去,在DAO层和控制层测试时是绑定了框架一起进行测试是有道理的,可以称之为集成单元测试。那么我还是有以下疑问: 1、这样做是正确的吗?大家都是怎么做的? 2、持续集成中运行单元测试包不包括这部分集成单元测试呢?还是仅包含测试业务逻辑的领域层测试 3、对于报表驱动的业务系统(类似于Kent他们第一次使用XP时做的那个系统),这样做正确吗?不过我们的业务也很复杂。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-10-07
引用 速度很慢,每次都要初始化那些XML配置文件 用一下spring-mock里提供的基类,支持缓存xml,其实就是把xml读取到static变量中,只初始化一次,就可以让所有的testCase共享,可以提高不少速度。 |
|
返回顶楼 | |
发表时间:2007-10-07
xyz20003 写道 引用 速度很慢,每次都要初始化那些XML配置文件
用一下spring-mock里提供的基类,支持缓存xml,其实就是把xml读取到static变量中,只初始化一次,就可以让所有的testCase共享,可以提高不少速度。 也就是说您也支持集成单元测试的观点,认为需要带着框架一起测试?还在接着看JUnit in Action,发现作者的观点也是在测试非POJO时推荐使用集成单元测试,而不推荐使用Mock。还在看,等再经过一些实践再交流~ |
|
返回顶楼 | |
发表时间:2007-10-08
经历过使用mock的阶段,使用mock比不使用mock的测试类大了10倍左右,估计是因为我没有经验,每个测试类都要用mock构建hibernate需要的条件。
后来是在觉得麻烦,干脆自己写stub,做了一个MockCriteria来测试,最后的结果是hql的语法错误,使用saveOrUpdate的问题根本检测不出来。转向使用集成测试后,代码清晰了,也能检测出问题来。 我的感觉是,除非hibernate或spring提供一套基于自己框架的mock类,支持自动拼装配置和错误提示,否则mock单元测试不但工作量大,而且没什么意义。 粗陋意见,有什么不妥的地方还请见谅。:) |
|
返回顶楼 | |
发表时间:2007-10-08
xyz20003 写道 经历过使用mock的阶段,使用mock比不使用mock的测试类大了10倍左右,估计是因为我没有经验,每个测试类都要用mock构建hibernate需要的条件。 后来是在觉得麻烦,干脆自己写stub,做了一个MockCriteria来测试,最后的结果是hql的语法错误,使用saveOrUpdate的问题根本检测不出来。转向使用集成测试后,代码清晰了,也能检测出问题来。 我的感觉是,除非hibernate或spring提供一套基于自己框架的mock类,支持自动拼装配置和错误提示,否则mock单元测试不但工作量大,而且没什么意义。 粗陋意见,有什么不妥的地方还请见谅。:) 对DAO一直用hsql来用测试以提高测试速度。 mock是用来测试一些难以实现的情况。 如果写stub比mock好那么mock就没有存在的意义了。 PS:我作的时候一个测试对应一个mock就不会乱了。及使测试类变大了也没什么关系。让他大去吧。。。 |
|
返回顶楼 | |
发表时间:2007-10-08
抛出异常的爱 写道 xyz20003 写道 经历过使用mock的阶段,使用mock比不使用mock的测试类大了10倍左右,估计是因为我没有经验,每个测试类都要用mock构建hibernate需要的条件。
后来是在觉得麻烦,干脆自己写stub,做了一个MockCriteria来测试,最后的结果是hql的语法错误,使用saveOrUpdate的问题根本检测不出来。转向使用集成测试后,代码清晰了,也能检测出问题来。 我的感觉是,除非hibernate或spring提供一套基于自己框架的mock类,支持自动拼装配置和错误提示,否则mock单元测试不但工作量大,而且没什么意义。 粗陋意见,有什么不妥的地方还请见谅。:) 对DAO一直用hsql来用测试以提高测试速度。 mock是用来测试一些难以实现的情况。 如果写stub比mock好那么mock就没有存在的意义了。 PS:我作的时候一个测试对应一个mock就不会乱了。及使测试类变大了也没什么关系。让他大去吧。。。 Oracle和hsql的表现有多一致,可以替用吗? mock不就是为了解决stub过于复杂才出来的吗? |
|
返回顶楼 | |
发表时间:2007-10-09
1不一致的话,正好可以提高可移植性
|
|
返回顶楼 | |
发表时间:2007-10-09
抛出异常的爱 写道 对DAO一直用hsql来用测试以提高测试速度。 mock是用来测试一些难以实现的情况。 如果写stub比mock好那么mock就没有存在的意义了。 PS:我作的时候一个测试对应一个mock就不会乱了。及使测试类变大了也没什么关系。让他大去吧。。。 应该是在下对hibernate内部实现不熟悉的问题,用easymock制作条件的时候,没有一次是直接成功的,每次都要试验好多次,才能确定getSessionFactory(),getSession()这些方法的具体调用次数。 后来感觉自己太古板,都设置成anyTimes(),即使这样,像setFlushMode()这类的方法,也经常遗漏,完全不知道是在什么时候调用的。 就这样,每次mock都要经历无数次反复的试验,才能把一个mock测试跑通,其中的功夫都是花在制定测试条件上的,苦不堪言。 想请教一下异常老大,怎么才能让mock制定测试条件的过程轻松一些,否则都没有体力去进行真正的测试了。 还是说,我本来的想法就错了。应该直接mock HibernateTemplate? |
|
返回顶楼 | |
发表时间:2007-10-09
连到数据 库的东东我都是用hsql来作的mock就有点太烦麻了。
用mock都是模拟些业务上的返回值问题。不是业务上的东东用stub来作。。。。 |
|
返回顶楼 | |
发表时间:2007-10-09
抛出异常的爱 写道 连到数据 库的东东我都是用hsql来作的mock就有点太烦麻了。
那看来异常老大跟我的做法是一样了,我现在用spring-mock提供的MockServletRequest来模拟业务请求,hibernate以下都是使用的实际数据库。 |
|
返回顶楼 | |
浏览 5473 次