锁定老帖子 主题:什么是“测试驱动开发”
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-04-25
partech 写道 firebody 写道 partech 写道 firebody 写道 一个误解,TDD是从顶向下进行边完善测试边设计的原则进行开发的。
测试完成了,设计也就完成了。 跟平常的考虑设计,写代码,写测试是不同的一个过程。 虽然这两种过程中的脑子里面的对于组件逻辑的构思很有可能完全一致。 但是TDD能够保证你脑子的构思在往好的方面发展,而不至于你脑子里面的“胡思乱想”。 测试和设计到底是什么关系? 一边构思设计一边构思怎么测试这个设计。 但是构思不是凭空想向,而是看着已经写下的测试代码进行的。 脑子的设计有了,不是先写代码,而是先按照构思的设计写期望的测试代码,测试失败,再完善代码。 就是这个关系。 这里有一个很重要的一点: 自顶向下的问题,越早写下的测试代码是越开始的对需求的设计分析。 你这里循环引用了,需要解耦。赫赫 哪里循环了? ![]() |
|
返回顶楼 | |
发表时间:2006-04-25
firebody 写道 一边构思设计一边构思怎么测试这个设计。 但是构思不是凭空想向,而是看着已经写下的测试代码进行的。 脑子的设计有了,不是先写代码,而是先按照构思的设计写期望的测试代码,测试失败,再完善代码。
就是这个关系。 |
|
返回顶楼 | |
发表时间:2006-04-25
这个只是自然归纳法,缺少一个n=0时的动作
|
|
返回顶楼 | |
发表时间:2006-04-25
firebody你在2006-4-25 12:50:17写的那段测试代码偶没看明白
看来看去没明白啊。 |
|
返回顶楼 | |
发表时间:2006-04-25
partech 写道 firebody 写道 一边构思设计一边构思怎么测试这个设计。 但是构思不是凭空想向,而是看着已经写下的测试代码进行的。 脑子的设计有了,不是先写代码,而是先按照构思的设计写期望的测试代码,测试失败,再完善代码。
就是这个关系。 哈哈,不好意思, 表述确实有问题。 整理一下: 构思设计,将设计用测试代码反映出来。 再实现设计代码,如果需要增加测试代码的,就完善测试代码。 |
|
返回顶楼 | |
发表时间:2006-04-25
charon 写道 firebody你在2006-4-25 12:50:17写的那段测试代码偶没看明白
看来看去没明白啊。 测试代码就是这么难看的啦,所以我就不完全同意gigix说得 它就是设计文档啊,我觉得用"是测试编写者的设计文档“更合适,因为除了他别人很不愿意看这样的代码的。 但是说句实话,我看所有的优秀的框架,都是先从测试代码开始看起的,因为那些框架的代码普遍都是输入输出的测试,很容易看得出大概来,如果是这种的中间状态的复杂处理,没有多少人愿意看的。 输入输出的测试代码更容易看懂。 一大堆Matcher ,mock代码是好的代码嘛? 或许TDD能够将测试代码带到更可读的境界。 我估计这两行代码: reportMatcher(。。。) 让你不大清楚吧。 我解析一下,那两行代码表示对参数状态的验证,他是在调用comp2.logic3 之前执行的验证,因为我把他放在mockComp1.logic3(result,result2); 之前。 看看我的源代码: doSomeInternalLogic1(result,result2);; comp2.logic3(result,result2);; 这里代码实现是先调用doSomeInternalLogic1改变result,result2的状态,然后传入comp2.logic3 。 我需要验证doSomeInternalLogic1的逻辑,就是验证执行完这个私有方法之后的result,result2的状态。 也就是被传入comp2.logic3方法的参数的状态 reportMatcher(IArgumentMatcher )可以帮助我从期望的调用方法中获得北传入的参数,然户进行参数状态的验证。 多少个参数,你就记录多少个Matcher. |
|
返回顶楼 | |
发表时间:2006-04-25
firebody 写道 partech 写道 firebody 写道 一边构思设计一边构思怎么测试这个设计。 但是构思不是凭空想向,而是看着已经写下的测试代码进行的。 脑子的设计有了,不是先写代码,而是先按照构思的设计写期望的测试代码,测试失败,再完善代码。
就是这个关系。 哈哈,不好意思, 表述确实有问题。 整理一下: 构思设计,将设计用测试代码反映出来。 再实现设计代码,如果需要增加测试代码的,就完善测试代码。 这样就矮化TDD了。 先有一个测试列表,从测试列表中拎出一个来实现 用assert固定这个测试,边写测试边写代码(就是说不是一口气把测试中所有的assert都搞定) 在测试过程中发现目标方法需要依赖其它的对象,mock it. 如果这个对象不存在,则把这个对象的测试添加到功能列表和测试列表 按我的理解,TDD所谓的推动,并不是说在推动你的方法的实现,而是在推动你对对象之间交互方式的设计和理解。针对的是依赖关系,而不是内部事务。 |
|
返回顶楼 | |
发表时间:2006-04-25
charon 写道 firebody 写道 partech 写道 firebody 写道 一边构思设计一边构思怎么测试这个设计。 但是构思不是凭空想向,而是看着已经写下的测试代码进行的。 脑子的设计有了,不是先写代码,而是先按照构思的设计写期望的测试代码,测试失败,再完善代码。
就是这个关系。 哈哈,不好意思, 表述确实有问题。 整理一下: 构思设计,将设计用测试代码反映出来。 再实现设计代码,如果需要增加测试代码的,就完善测试代码。 这样就矮化TDD了。 先有一个测试列表,从测试列表中拎出一个来实现 用assert固定这个测试,边写测试边写代码(就是说不是一口气把测试中所有的assert都搞定) 在测试过程中发现目标方法需要依赖其它的对象,mock it. 如果这个对象不存在,则把这个对象的测试添加到功能列表和测试列表 按我的理解,TDD所谓的推动,并不是说在推动你的方法的实现,而是在推动你对对象之间交互方式的设计和理解。针对的是依赖关系,而不是内部事务。 是的,正如我前面所说的,TDD测试最大的可读性就是与mock对象的交互。 但是正如我们最后争论焦点一样,是否应该把那个私有的方法抽出来放到单独的一个类呢? TDD可以帮助你做这个决定。 但是,如果直接用matcher来一样可以测试那个私有方法的逻辑,只不过测试代码的可读性大大降低了。 |
|
返回顶楼 | |
发表时间:2006-04-25
firebody 写道 charon 写道 firebody你在2006-4-25 12:50:17写的那段测试代码偶没看明白
看来看去没明白啊。 测试代码就是这么难看的啦,所以我就不完全同意gigix说得 它就是设计文档啊,我觉得用"是测试编写者的设计文档“更合适,因为除了他别人很不愿意看这样的代码的。 但是说句实话,我看所有的优秀的框架,都是先从测试代码开始看起的,因为那些框架的代码普遍都是输入输出的测试,很容易看得出大概来,如果是这种的中间状态的复杂处理,没有多少人愿意看的。 输入输出的测试代码更容易看懂。 一大堆Matcher ,mock代码是好的代码嘛? 或许TDD能够将测试代码带到更可读的境界。 我估计这两行代码: reportMatcher(。。。) 让你不大清楚吧。 我解析一下,那两行代码表示对参数状态的验证,他是在调用comp2.logic3 之前执行的验证,因为我把他放在mockComp1.logic3(result,result2); 之前。 看看我的源代码: doSomeInternalLogic1(result,result2);; comp2.logic3(result,result2);; 这里代码实现是先调用doSomeInternalLogic1改变result,result2的状态,然后传入comp2.logic3 。 我需要验证doSomeInternalLogic1的逻辑,就是验证执行完这个私有方法之后的result,result2的状态。 也就是被传入comp2.logic3方法的参数的状态 reportMatcher(IArgumentMatcher )可以帮助我从期望的调用方法中获得北传入的参数,然户进行参数状态的验证。 多少个参数,你就记录多少个Matcher. 看了这个代码。基本确认我们说的不是一个事情。 如果只是要验证comp2.logic3的传入参数,不必费那么大劲。因为EasyMock默认的就是equals方式的参数匹配。在外面构造好合适的result,result2不就行了。不理解为什么要自己构造IArgumentMatcher的实例(之前的不理解主要就在这里,不了解构造这个的必要性) 而要验证doSomeInternalLogic之类方法对状态的影响,这是间接方式。太琐碎了。而且不能应付大多数情况。 |
|
返回顶楼 | |
发表时间:2006-04-25
charon 写道 看了这个代码。基本确认我们说的不是一个事情。 如果只是要验证comp2.logic3的传入参数,不必费那么大劲。因为EasyMock默认的就是equals方式的参数匹配。在外面构造好合适的result,result2不就行了。不理解为什么要自己构造IArgumentMatcher的实例(之前的不理解主要就在这里,不了解构造这个的必要性) 而要验证doSomeInternalLogic之类方法对状态的影响,这是间接方式。太琐碎了。而且不能应付大多数情况。 嗯,我也有这种感觉。 从测试代码来看,是比较evil的。 跟AssertEquals之类比起来确实没法比。 不过,不大理解的是,在私有方法改变状态的逻辑 上,除了改成protected和抽取出另外一个组件之外,似乎也就只有这么一个办法了。 我要验证doSomeInternalLogic的逻辑,就只能构造那两个ArgumentMatcher来进行验证。 |
|
返回顶楼 | |