浏览 4951 次
锁定老帖子 主题:对TDD是那么的困惑
精华帖 (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仍旧非常困惑迷茫,所以希望通过此篇跟大家交流。谢谢! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间: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不测...(太难测了还不如用眼睛看) |
|
返回顶楼 | |
发表时间:2008-09-24
抛出异常的爱 写道 把需求1拆成至少三个故事. 把需求2拆成至少五个故事. 你的意思是不是 需求1=从一个固定的地方列出所有的用户展现到界面上? 需求2=界面存在一个新增按钮可添加一个用户,添加完毕后刷新用户列表? 如果是的话,那拆成怎样三个故事呢? 抛出异常的爱 写道 PS:action+jsp不测...(太难测了还不如用眼睛看) jsp先在白纸上画的,主要是将需求展现出来 因为眼睛看着白纸,所以自然的先想到action,这样action编写出来基本满足白纸上的需求,所以对action进行了测试,其实一点都不想测action,但是为了第一线从需求出发,硬着头皮去mock那么多玩意~ |
|
返回顶楼 | |
发表时间: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过程再现一次. |
|
返回顶楼 | |
发表时间: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不进行重复测试了 |
|
返回顶楼 | |
发表时间: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条不能算是用户故事。只能是实现步骤吧? |
|
返回顶楼 | |
发表时间:2008-12-03
TDD本来就该没有这么麻烦,用户故事应该有适合的粒度,实际上能够方便测试\开发就好了...
|
|
返回顶楼 | |
发表时间:2008-12-03
TDD是一种好的开发方法,刚开始可能会乱,但我的practice,TDD不仅仅是一处开发技术,更重要的是其中的思维...
|
|
返回顶楼 | |