论坛首页 综合技术论坛

对TDD是那么的困惑

浏览 4951 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-09-24  
首先我同意测试驱动等同于需求驱动,因为编写测试代码都是为来自需求。我希望使用一个例子来阐述实现步骤。

用例:列出系统的所有操作用户,并可添加用户
任务1、从一个固定的地方列出所有的用户展现到界面上
任务2、界面存在一个新增按钮可添加一个用户,添加完毕后刷新用户列表

开发的是Web应用,所以我认为在纸上或者白板上画出需求中所描述的界面原型最直观。另外系统采用传统J2EE分层:action、service、dao。
挑选任务1,从action入手,理由:action最贴近界面,也可以理解为最贴近需求(很牵强的理由,但是目前我就是这样认为的)
(1)action应该有一个list方法,从一个固定的地方获取用户列表,并通过HttpServletRequest.setAttribute到一个变量中以提供给jsp渲染,最终跳转到期望的actionForward。
断言1:从一个固定地方获取用户列表交给service更合理些,所以应该mock一个service传递给action,保证列表是从service.list获取的。编写测试,并保证断言1通过
断言2:列表应该设置到HttpServletRequest中去,所以应该mock一个HttpServletRequest,然后HttpServletRequest.setAttribute被调用到。编写测试,并保证断言2通过
断言3:保证跳转到list.jsp。采用struts,我判断返回值是否为"list"。编写测试,并保证断言3通过。
这样实现了action.list。
(2)衍生出一个service接口,service.list需要实现的是“一个固定的地方获取用户列表”,这个固定的地方需要通过通过dao访问
断言1:应该mock一个dao,我要保证的是service.list返回的用户列表通过dao.list方法调用的。编写测试,并保证断言1通过
这样实现了service.list。
(3)衍生出一个dao接口,dao.list需要实现的是从数据库获取用户列表,使用hsql
断言1:从空表中获取列表,siaze=0。编写测试,并保证断言1通过
断言2:插入一条记录到空表,从表中获取列表,sise=1,并且获取的是刚才插入的那条记录。编写测试,并保证断言2通过
(4)所有的单元测试到此为止,实现jsp、配置xml文件,启动server检验界面、配置是否正确,排版是否合理。

以上只挑了任务1作为说明,任务2如法炮制,主要意图阐述TDD开发Web应用实现流程,其中忽略了重构的步骤。
目前对TDD仍旧非常困惑迷茫,所以希望通过此篇跟大家交流。谢谢!
   发表时间:2008-09-24  
withoutmewang 写道
首先我同意测试驱动等同于需求驱动,因为编写测试代码都是为来自需求。我希望使用一个例子来阐述实现步骤。

用例:列出系统的所有操作用户,并可添加用户
任务1、从一个固定的地方列出所有的用户展现到界面上
任务2、界面存在一个新增按钮可添加一个用户,添加完毕后刷新用户列表

开发的是Web应用,所以我认为在纸上或者白板上画出需求中所描述的界面原型最直观。另外系统采用传统J2EE分层:action、service、dao。
挑选任务1,从action入手,理由:action最贴近界面,也可以理解为最贴近需求(很牵强的理由,但是目前我就是这样认为的)
(1)action应该有一个list方法,从一个固定的地方获取用户列表,并通过HttpServletRequest.setAttribute到一个变量中以提供给jsp渲染,最终跳转到期望的actionForward。
断言1:从一个固定地方获取用户列表交给service更合理些,所以应该mock一个service传递给action,保证列表是从service.list获取的。编写测试,并保证断言1通过
断言2:列表应该设置到HttpServletRequest中去,所以应该mock一个HttpServletRequest,然后HttpServletRequest.setAttribute被调用到。编写测试,并保证断言2通过
断言3:保证跳转到list.jsp。采用struts,我判断返回值是否为"list"。编写测试,并保证断言3通过。
这样实现了action.list。
(2)衍生出一个service接口,service.list需要实现的是“一个固定的地方获取用户列表”,这个固定的地方需要通过通过dao访问
断言1:应该mock一个dao,我要保证的是service.list返回的用户列表通过dao.list方法调用的。编写测试,并保证断言1通过
这样实现了service.list。
(3)衍生出一个dao接口,dao.list需要实现的是从数据库获取用户列表,使用hsql
断言1:从空表中获取列表,siaze=0。编写测试,并保证断言1通过
断言2:插入一条记录到空表,从表中获取列表,sise=1,并且获取的是刚才插入的那条记录。编写测试,并保证断言2通过
(4)所有的单元测试到此为止,实现jsp、配置xml文件,启动server检验界面、配置是否正确,排版是否合理。

以上只挑了任务1作为说明,任务2如法炮制,主要意图阐述TDD开发Web应用实现流程,其中忽略了重构的步骤。
目前对TDD仍旧非常困惑迷茫,所以希望通过此篇跟大家交流。谢谢!

把需求1拆成至少三个故事.
把需求2拆成至少五个故事.


PS:action+jsp不测...(太难测了还不如用眼睛看)


0 请登录后投票
   发表时间:2008-09-24  
抛出异常的爱 写道

把需求1拆成至少三个故事.
把需求2拆成至少五个故事.

你的意思是不是
需求1=从一个固定的地方列出所有的用户展现到界面上?
需求2=界面存在一个新增按钮可添加一个用户,添加完毕后刷新用户列表?

如果是的话,那拆成怎样三个故事呢?

抛出异常的爱 写道

PS:action+jsp不测...(太难测了还不如用眼睛看)


jsp先在白纸上画的,主要是将需求展现出来
因为眼睛看着白纸,所以自然的先想到action,这样action编写出来基本满足白纸上的需求,所以对action进行了测试,其实一点都不想测action,但是为了第一线从需求出发,硬着头皮去mock那么多玩意~
0 请登录后投票
   发表时间:2008-09-24  
withoutmewang 写道
抛出异常的爱 写道

把需求1拆成至少三个故事.
把需求2拆成至少五个故事.

你的意思是不是
需求1=从一个固定的地方列出所有的用户展现到界面上?
需求2=界面存在一个新增按钮可添加一个用户,添加完毕后刷新用户列表?

如果是的话,那拆成怎样三个故事呢?

抛出异常的爱 写道

PS:action+jsp不测...(太难测了还不如用眼睛看)


jsp先在白纸上画的,主要是将需求展现出来
因为眼睛看着白纸,所以自然的先想到action,这样action编写出来基本满足白纸上的需求,所以对action进行了测试,其实一点都不想测action,但是为了第一线从需求出发,硬着头皮去mock那么多玩意~

1.1 查寻所有的用户.....(hsql)jdbc,hibernate,或其它东西
1.2 把rs中的数据导入用来显示的list(这个没什么逻辑但还是要写的.)
1.3 如果是struts2的话.action中的属性测试一下(mock一下service)就可以了如果是1的话,根本不测.

第二个
2.1 service配出一个用户模版(这个不用mock)
2.2 service得到用户信息(这个需要mock出人添制过程)
2.3 新建一个用户在数据库中(这个需要mock出DB)\
2.4 hsql插入数据
2.5 把1.2过程再现一次.


0 请登录后投票
   发表时间:2008-09-24  
这样是否符合你的意思:
1、空表size应该为0
2、向空表插入一个用户应当使返回列表size=1
3、向空表插入一个用户,返回列表中应该包含这个用户,并且没有任何其他的用户
至于使用jdbc,hibernate,ibatis还是其他,提供不同的测试类分别测试。
与你存在差异的地方是,以上步骤都是在dao中验证,而且插入用户直接通过dao.insert做掉了,所以dao.insert与dao.get一般是一起测掉了。也有其他方法,比如在hsql加载时就通过脚本插入若干条测试用户记录,或者在测试类中手写sql插入。

service只测流程,如上面提到的service,它只需要返回dao.list返回的用户列表,没有其他逻辑,那么我只测试dao.list是否被调用,并service.list返回的是否是dao.list返回的值。所以在dao中测试过的,在service不进行重复测试了
0 请登录后投票
   发表时间:2008-09-25  
抛出异常的爱 写道
withoutmewang 写道
抛出异常的爱 写道

把需求1拆成至少三个故事.
把需求2拆成至少五个故事.

你的意思是不是
需求1=从一个固定的地方列出所有的用户展现到界面上?
需求2=界面存在一个新增按钮可添加一个用户,添加完毕后刷新用户列表?

如果是的话,那拆成怎样三个故事呢?

抛出异常的爱 写道

PS:action+jsp不测...(太难测了还不如用眼睛看)


jsp先在白纸上画的,主要是将需求展现出来
因为眼睛看着白纸,所以自然的先想到action,这样action编写出来基本满足白纸上的需求,所以对action进行了测试,其实一点都不想测action,但是为了第一线从需求出发,硬着头皮去mock那么多玩意~

1.1 查寻所有的用户.....(hsql)jdbc,hibernate,或其它东西
1.2 把rs中的数据导入用来显示的list(这个没什么逻辑但还是要写的.)
1.3 如果是struts2的话.action中的属性测试一下(mock一下service)就可以了如果是1的话,根本不测.

第二个
2.1 service配出一个用户模版(这个不用mock)
2.2 service得到用户信息(这个需要mock出人添制过程)
2.3 新建一个用户在数据库中(这个需要mock出DB)\
2.4 hsql插入数据
2.5 把1.2过程再现一次.




怎么看都怎么觉得异常写的这8条不能算是用户故事。只能是实现步骤吧?

0 请登录后投票
   发表时间:2008-12-03  
TDD本来就该没有这么麻烦,用户故事应该有适合的粒度,实际上能够方便测试\开发就好了...
0 请登录后投票
   发表时间:2008-12-03  
TDD是一种好的开发方法,刚开始可能会乱,但我的practice,TDD不仅仅是一处开发技术,更重要的是其中的思维...
0 请登录后投票
论坛首页 综合技术版

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