06|TDD中的测试(2):行为验证为什么应该尽量避免使用?
徐昊
你好,我是徐昊。今天我们来继续学习测试驱动开发中的测试。
上节课我们介绍了测试的基础结构——四阶段测试,也就是将每个测试都看作四个依次执行的阶段:初始化、执行测试、验证结果和复原。并且,我们还着重介绍了该如何使用状态验证来验证测试的结果。
今天这节课,我们将介绍另一种验证方式——行为验证,以及为什么你应该尽量避免使用它。
验证结果——行为验证
行为验证是指通过待测系统与依赖组件(Depended On Component)的交互,来判断待测系统是否满足需求的验证方式。其验证方式如下图所示:
行为验证背后的逻辑是,状态的改变是由交互引起的。如果所有的交互都正确,那么就可以推断最终的状态也不会错。例如,对于如下的代码:
功能需求是 SUT 的 action 方法调用计数器 Counter 使其计数增加。按照状态验证,我们需要从 Counter 中获取内部计数,然后判断在执行测试前后,计数是否增加。
而对于行为验证,因为计数增加与否只在于是否调用了 increase 方法。那么如果 SUT 调用了 increase 方法,我们就可以推测Counter 的计数也必然增加了。
于是,我们可以将对于读数增加的验证,转化为对于 increase 方法调用的验证:如果 increase 方法被调用了,那么我们可以推测SUT 是满足功能需求的。状态验果,行为推因。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
TDD中的测试(2):行为验证为什么应该尽量避免使用? 本文介绍了测试驱动开发(TDD)中的测试方式——行为验证,并探讨了为什么应该尽量避免使用它。行为验证是通过待测系统与依赖组件的交互来验证系统是否满足需求,但文章指出了行为验证可能会阻碍TDD的进行,因为它与TDD的核心逻辑冲突。文章强调了在TDD中应尽量使用状态验证,而行为验证可能会丧失测试的有效性,特别是在依赖复杂的框架或进程外组件的情况下。虽然行为验证在特定场景下是有用的,但并不适合作为TDD的默认验证方式。文章还提到了降低测试成本的其他选择,如Test Container、Mountebank等进程外测试替身,并呼吁读者在特定情况下思考何时使用行为验证既不会影响重构又能降低测试成本。文章以此引出了对TDD的思考和实践的重要性,并介绍了“TDD专栏首发·代码评点”活动,鼓励读者动手实操、反复练习,以提高技能水平。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《徐昊 · TDD 项目实战 70 讲》,新⼈⾸单¥98
《徐昊 · TDD 项目实战 70 讲》,新⼈⾸单¥98
立即购买
登录 后留言
全部留言(20)
- 最新
- 精选
- 邓志国对一些第三方系统的使用,比如发送短信。我可能只需要关心短信发送这个动作是否被调用了,那么这个时候Mock发短信的动作我觉得是可以的。
作者回复: good
2022-03-22223 - leesper老师,看你讲到领域模型,那您一定也是DDD高手嘛?能开个课讲讲DDD吗,感觉落地好难
编辑回复: 在极客时间上搜《如何落地业务建模》,也是徐昊老师的课,里面讲有DDD
2022-08-18归属地:北京3 - byemoto《Google软件工程》书中第13章提到,在有些情况下,交互测试是必要的: 1. 不能使用实际实现或伪实现。 2. 调用函数的次数或顺序的差异会导致非预期的行为。 这里的交互测试即行为验证。
作者回复: 尽量避免 是副作用大 不是没用
2022-04-281 - Adoy对于想OptionParser这样设计成Inverse of Control风格的API,mock一个parser来做行为验证比较合理。类似的前端onClick,onChange这样的API,行为验证的测试实现起来更简单直观,也不影响组建内部的重构。
作者回复: 你可以试试
2022-03-2221 - lvxus参照测试金字塔,层级最高的那层使用行为测试,应该符合减少成本而又不太影响重构?
作者回复: 可以重新思考一下测试金字塔到底是什么
2022-04-23 - Sudouble功能、结构本身改动不大之处,适用于行为验证。基于行为的验证不合适的主要原因在于实现方式变化,以及无法感知到实现变化后,实际输入输出变化。相应的,主要思考在于哪个位置变化小?可以推广至再上层的集成测试、功能测试级别,或者说API接口。
作者回复: 如果能预知改变 就不用这么麻烦了
2022-04-10 - davix請教函數式編程中的測試一般是哪種類型?
作者回复: 看风格 代码点评里 我写了一个high order组合风格。cps,mondic测试技巧都不太一样
2022-04-09 - 阿崔cxr找到程序的边界,对于那些非自己程序的逻辑,比如第三方库,就可以 mock 掉。也就是使用行为测试
作者回复: 那为啥不fake
2022-03-23 - 邓志国如果我的业务逻辑依赖于一个Repository接口,我用内存实现了一个这样的接口。比如测试一个新增后,我会去这个Repository内存实现中查找到新增的对象。这样的测试替身算是行为验证还是状态验证?
作者回复: 状态验证
2022-03-22 - 程序袁帅我之前把《Mock 不是 Stub》这篇文章翻译成了中文,分享给大家: https://www.yuque.com/yuanshenjian/agile/mocks-are-not-stubs 这篇文章有点长,但仔细读两遍,会有很多收获,可以作为CTO专栏的很好补充2022-04-0529
收起评论