2007-02-14
如何写完备的单元测试,写了这些测试给我们带来了什么?
最近在改一个其他公司几年前做的一个信用卡系统,因为年代久远,需求、代码的不全面,导致对同一个问题不断的修改。
需求1:导入大机的打卡文件,文件是一个文本文件,每行是一条记录,根据其中的联名编号找卡种,联名编号只有两种,8位编号或者8个0。如果没有找到卡种则报错退出。(联名编号是信用卡联名组织的一个编号,比如中石油卡,联名组织是中石油)
对卡种表加一个字段保存联名编号,默认值是8个0,然后一条sql解决问题:select * from cardtype where jointlyno = ?
上线后出问题了:运通卡文件无法导入。
调试跟踪后发现,运通卡的打卡文件的联名编号是8个空格,和以前的需求描述不一样,只好修改代码。
得到的需求是--需求2:如果是8个空格的肯定是运通卡
于是代码变成了先判断jointlyno是否是8个空格,如果是则直接返回全部的运通卡卡种,不是才是以前的那条sql
上线后又出问题了,有一个文件导入报错,没有说明什么卡等具体细节。
只好把那个文件拿过来调试跟踪,发现是有两个卡种比较怪异,他们的联名编号是10013xxx,3个x表示可以随意变化,因为这个是学生卡,3个x表示的是学校编号。问题就出现在这里,打卡文件里面的联名编号是确定的,比如是10013001,但是卡种表里面的却是10013xxx,所以按照那条sql 返回的记录是空。
看来只好继续改程序,变成了再加一个判断,如果联名编号前五位是10013的则不管后面3位是什么,判断前五位即可。即select * from cardtype where substr(jointlyno,1,5)= ? ,这个 ?是 jointlyNo.subString(0,5)。
这里出现一个 需求3:如果联名编号前五位是10013的则不管后面3位是什么,判断前五位即可
这么一个简单的问题为什么需要反反复复的修改呢?能否避免反复修改?如果无法避免,如果有效快速地应对这些修改?
这个案例很显然地原因就是客户对需求理解的不全面,以致于他自己在不断完善自己的需求,而代码也跟着需求在修改,这个修改是无法避免的,如果无法反抗,按照敏捷的做法那就拥抱变化吧,问题是怎么拥抱?我觉得需要用完备的测试来细化对需求的理解。
对于需求1,需要测试三种情况,1) 00000000 2) 正确的联名编号 3)错误的联名编号
8个空格就是第三种情况,10013001也是第三种情况。 但是这种情况都是在需求1中被客户声明说不会出现的情况,恰恰变化就出在这边。需求的变化是把几个错误的编号变成了正确的编号,这种完全相反的变化完全无法预料的。
需求2出现后 需要增加 一个 8个空格的测试,非8个空格的测试落入刚才3个测试中。
需求3出现后 需要增加 1)10013001的测试,2)10013888(假设10013888这个联名编号存在,而且对应的卡种不是学生卡) 3)10013999(10013999是一个不存在的联名编号)
如果第2、3两个测试的情况发生,那现在的代码就有bug。但是现在需求是10013开头的联名编号肯定对应的学生卡,这两个杞人忧天的测试需要吗?
很简单的一个问题,但是要写这么多的测试,每个case要写完备的测试真不是一件简单的事情,不知道有什么成套的测试写法。而且这些测试带来的作用仅仅是对需求的细化理解,并不能对代码的修改产生多大的帮助。这些测试如果用图来表达其实也不错,为何一定需要这么完备的单元测试代码呢?
需求1:导入大机的打卡文件,文件是一个文本文件,每行是一条记录,根据其中的联名编号找卡种,联名编号只有两种,8位编号或者8个0。如果没有找到卡种则报错退出。(联名编号是信用卡联名组织的一个编号,比如中石油卡,联名组织是中石油)
对卡种表加一个字段保存联名编号,默认值是8个0,然后一条sql解决问题:select * from cardtype where jointlyno = ?
上线后出问题了:运通卡文件无法导入。
调试跟踪后发现,运通卡的打卡文件的联名编号是8个空格,和以前的需求描述不一样,只好修改代码。
得到的需求是--需求2:如果是8个空格的肯定是运通卡
于是代码变成了先判断jointlyno是否是8个空格,如果是则直接返回全部的运通卡卡种,不是才是以前的那条sql
上线后又出问题了,有一个文件导入报错,没有说明什么卡等具体细节。
只好把那个文件拿过来调试跟踪,发现是有两个卡种比较怪异,他们的联名编号是10013xxx,3个x表示可以随意变化,因为这个是学生卡,3个x表示的是学校编号。问题就出现在这里,打卡文件里面的联名编号是确定的,比如是10013001,但是卡种表里面的却是10013xxx,所以按照那条sql 返回的记录是空。
看来只好继续改程序,变成了再加一个判断,如果联名编号前五位是10013的则不管后面3位是什么,判断前五位即可。即select * from cardtype where substr(jointlyno,1,5)= ? ,这个 ?是 jointlyNo.subString(0,5)。
这里出现一个 需求3:如果联名编号前五位是10013的则不管后面3位是什么,判断前五位即可
这么一个简单的问题为什么需要反反复复的修改呢?能否避免反复修改?如果无法避免,如果有效快速地应对这些修改?
这个案例很显然地原因就是客户对需求理解的不全面,以致于他自己在不断完善自己的需求,而代码也跟着需求在修改,这个修改是无法避免的,如果无法反抗,按照敏捷的做法那就拥抱变化吧,问题是怎么拥抱?我觉得需要用完备的测试来细化对需求的理解。
对于需求1,需要测试三种情况,1) 00000000 2) 正确的联名编号 3)错误的联名编号
8个空格就是第三种情况,10013001也是第三种情况。 但是这种情况都是在需求1中被客户声明说不会出现的情况,恰恰变化就出在这边。需求的变化是把几个错误的编号变成了正确的编号,这种完全相反的变化完全无法预料的。
需求2出现后 需要增加 一个 8个空格的测试,非8个空格的测试落入刚才3个测试中。
需求3出现后 需要增加 1)10013001的测试,2)10013888(假设10013888这个联名编号存在,而且对应的卡种不是学生卡) 3)10013999(10013999是一个不存在的联名编号)
如果第2、3两个测试的情况发生,那现在的代码就有bug。但是现在需求是10013开头的联名编号肯定对应的学生卡,这两个杞人忧天的测试需要吗?
很简单的一个问题,但是要写这么多的测试,每个case要写完备的测试真不是一件简单的事情,不知道有什么成套的测试写法。而且这些测试带来的作用仅仅是对需求的细化理解,并不能对代码的修改产生多大的帮助。这些测试如果用图来表达其实也不错,为何一定需要这么完备的单元测试代码呢?
- 10:29
- 浏览 (4403)
- 论坛浏览 (5230)
- 评论 (8)
- 分类: Programming
- 相关推荐
评论
测试就是分解后的需求
。。。。。
如果需求变了找到这些测试修改之
。。。。。
需求变更的过程就是不停的修改测试用例的过程
如何写一个可用的测试?
1.一般例
2.特例
3.可能出现的特例但现在没有提出来的,不必写测试
4.不可能出现的特例 抛异常(就是你说的那两种卡)。
写测试之前要先把你说的图画出来
测试是文档化,可自动检查的图形。
用人的眼睛来比较图与代码的区别,
那是上世纪的活,这个世纪不用了。
。。。。。
如果需求变了找到这些测试修改之
。。。。。
需求变更的过程就是不停的修改测试用例的过程
如何写一个可用的测试?
1.一般例
2.特例
3.可能出现的特例但现在没有提出来的,不必写测试
4.不可能出现的特例 抛异常(就是你说的那两种卡)。
写测试之前要先把你说的图画出来
测试是文档化,可自动检查的图形。
用人的眼睛来比较图与代码的区别,
那是上世纪的活,这个世纪不用了。
从楼主例子可见需求本身就是这么复杂,就算不做单元测试,在集成测试的时候,每种情况也必须测试到位。写入单元测试,测起来更快捷。不要指望可以减少对某些情况的测试,因为这样做提高了风险。
我的理解:单元测试最重要的作用是及早发现问题,以降低修复问题的成本。体现在开发过程中就是不需要进行系统集成测试就能发现问题。例如重构之后运行单元测试就能确认是否存在问题,或者编码结束后,立刻就可以使用单元测试发现问题。所以说xp并不是拉平“时间-成本”曲线,而是将开发与修改bug直接连起来,将修改的成本降到最低,然后通过迭代来连接“开发-修改bug”的循环。
具体到楼主的情况,如果进行集成测试的成本很高,那么写单元测试就是很好的方式,因为单元测试成本很低,如果单元测试执行得很好,就可能达成集成测试一次过关的目标。反之如果集成测试的成本非常低,那么写单元测试相对来说价值就降低了。一般情况下,写几个单元测试的成本肯定比进行好几次集成测试的成本低。
至于说单元测试能为以后的重构带来好处,我想对于楼主的项目来说应该是可以忽略的。
一家之言,欢迎讨论。
具体到楼主的情况,如果进行集成测试的成本很高,那么写单元测试就是很好的方式,因为单元测试成本很低,如果单元测试执行得很好,就可能达成集成测试一次过关的目标。反之如果集成测试的成本非常低,那么写单元测试相对来说价值就降低了。一般情况下,写几个单元测试的成本肯定比进行好几次集成测试的成本低。
至于说单元测试能为以后的重构带来好处,我想对于楼主的项目来说应该是可以忽略的。
一家之言,欢迎讨论。
daquan198163
2007-02-15
回复
自动回归、给你信心、快速反馈,单元测试的这几个好处几乎在哪里都适用的;
凡是可能出错的地方终究斗会出错,所以还是需要测的
凡是可能出错的地方终究斗会出错,所以还是需要测的
发表评论
该博客是同时发布到论坛的,无法评论在论坛已被锁定的帖子
- 浏览: 394583 次
- 性别:

- 来自: 上海

- 详细资料
搜索本博客
我的相册
Gmail
共 8 张
共 8 张
最新评论
-
JIRA不完全手册
楼主,发一份完整的资料给我吧 xwj1003@yahoo.com.cn
-- by volking -
java encoding参考
Good ,thanks.
-- by zuowei -
有多少异常可以重来
我今天也遇到这个问题,才搜到这个帖子~ 还没有解决,等恢复哦
-- by javamanlcy007 -
有多少异常可以重来
这个错误解决了,又抱了别的错误~
-- by iceworld4143 -
有多少异常可以重来
解释不太懂,我也遇到这个问题了,可是我没用ant。 :cry: 等回 ...
-- by iceworld4143






评论排行榜