10 月 23 - 25 日,QCon 上海站即将召开,现在购票,享9折优惠 了解详情
写点什么

“Classic”与“Mockist”TDD,真的对立么?

  • 2009-02-10
  • 本文字数:2102 字

    阅读完需:约 7 分钟

这周 Yahoo“测试驱动开发(TDD)”小组里面有个热门贴子,是讨论“classic”和“mockist”TDD 方式之间的对立统一关系。Steve Freeman、Nat Pryce、Michael Feathers、Dale Emery 等很多人对这些术语进行了讨论,并描述了各自的工作方式。他们也探讨了是否确实存在这种关系。如果存在这种关系,又是什么从本质上区分开这两种方式?

在声明自己“倾向于classic TDD 开发方法”之后, Olaf Bjarnason 在小组里面用问题——“如果你以前采用 classic(方式),是什么让你转向 [‘mockist’]?觉得新方法怎么样?”——发起了一场超过 70 条贴子的讨论。然而,前期的回复大多是围绕着 Olaf 的贴子标题“classic/mockist 讨论”进行的,即是否确有必要进行如此绝对对立的划分。

JMock 的合作创始人 Nat Pryce 表达了他的看法

我认为把 TDD 分成“mockist”和“基于状态”是没有意义的,不仅分散了关注点,而且妨碍人们去尝试学习和实践 TDD。

Mock 对象只是一种工具,只是实践 TDD 时会使用到的工具之一。跟其他工具一样,它们被设计出来以帮助解决特定上下文的一系列问题。脱离了上下文,它们不会有任何帮助,甚至成为障碍。

如果确实如此,那怎么知道该何时使用这种“工具”呢?怎么判断该测试“状态”(不使用 mock),还是该验证行为(使用 mock)?

Dale Emery 也加入讨论,讲了他一般是怎么区分的:

很多人使用“基于状态”和“基于行为”的说法来区分。我换了种说法,我认为是“结果”和“协议”。如果是测试 UUT(unit under test,被测试单元)是否返回了正确的结果,我通常不使用 mock。如果是测试 UUT 是否基于协议扮演了恰当的角色——比如,给定正确的起始条件和影响因素,(UUT)是否向正确的协作者发送了正确消息——我会用 mock 来代替 UUT 的直接协作者。

Lior Friedman 认为mock 的用途是展示一种契约:

对我来说,mock 指出了被测试覆盖的类和被(该类)调用的其他类之间存在的“契约”。(mock)测试的目的是确保契约被满足了。

Charlie Poole 就“什么时候使用基于状态(的测试)”提出了他的论断:

如果没有其他办法来观察对象的行为,也就是说如果方法调用只会引起对象外界可观察状态的改变,我会选择基于状态的测试。而假如事实上对象做了些什么,我会 [使用 mock] 验证它的确是做了。

Adam Sroka 解释了他何时使用 mock:

就我个人而言,我通常是在系统定义的边界处(比如文件系统、网络、数据库等)使用 mock。在自顶而下的开发中,为了得到接口和客户端的松耦合,我通常会使用 mock。相反,当交互的对象很小、易于用假对象 /stub 对象替代时,我一般不使用 mock。

随着讨论的继续,讨论中反复出现这样的现象(可能上文的摘录也体现了这点):虽然不少贴子的观点类似,但是它们并没有使用通用的分类和命名,只是强调“我们有时这么做,其他时候不是”。而且,每个贴子(可能除了 Sroka“自顶而下”的论断)关注更多的是:到底是设计驱动 mock,抑或相反,mock 驱动设计?

关于 mock 驱动设计,Michael Feathers 给出了如下例子:

对我来说,问题的根本在于人们愿意在多大程度上遵循“tell, don’t ask.”mocks 支持了这种设计方式。 …

假设你拥有某一类对象,想得到它的错误: class Errors {
int errorCount();
Error getError(int index);
}

Errors errors = object.getErrors();

这就是 _ask_。我们可以基于状态对 Errors 对象进行测试。为了改成 _tell_,你需要进行如下处理: interface ErrorReceiver {
void accept(Error error);
}

ErrorReceiver receiver = …;

object.reportErrors(receiver);
我们可以对 mock 的 receiver 对象指定预期行为,使之通过测试,而在生产代码中使用“真实”的类。

Steve Freeman(JMock 的另一位合作开发者)发表了一篇贴子,描述了他的搭档 Nat Pryce 对一些“值得 mock 的相关对象组(mock-worthy peer objects)”提出的分类(“Dependencies”,“Notifications”和“Policies”)。在回应的贴子中, Feathers (以及 Colin Jack )认为他们两人(Freeman 和 Pryce)提出的设计理念实际上就是“mock 驱动设计”哲学的核心的一部分。在接下来的讨论中,扼要的讲,当人们提到“mockist TDD”,主要是指这些理念。而且,随着这些更具体的名字,之前反复出现的关于“classic 与 Mockist TDD”的混淆也减少了。

Pryce 提醒小组成员,他和 Freeman 计划写一本书,提供一些这方面需要的解释。同时他也建议小组成员去参阅他的一篇文章“基于状态与交互的测试”。

坦率的说,这种讨论并不是什么新货色(Google 一下),过一段时间就会出现一次。是否存在着“classic TDD”,而它是否又意味着“设计引出mock”或者其他特性?是否存在“mockist TDD”,体现着“mock 引出设计”的哲学?“Tell, Don’t Ask”,这是否又是完全不相干的东西?不管怎样,这是一种“非此即彼”的分类么,又或者“这种适合这些,那种适合那些”的分类更合适?

当然,一如既往,本文只是摘录了 Yahoo 小组讨论中的突出部分 [希望本文是客观的],仅仅是完整讨论的一部分。你可以自行阅读该贴以及其他相关资料,在这里或讨论贴里与其他人分享你的经验。

查看英文原文“Classic” versus “Mockist” TDD, Distinction Real?

2009-02-10 02:092126
用户头像

发布了 76 篇内容, 共 27.5 次阅读, 收获喜欢 3 次。

关注

评论

发布
暂无评论
发现更多内容

Web3流量聚合平台Starfish OS,给玩家元宇宙新范式体验

鳄鱼视界

let's go——2022年读书活动招募书(第1期)

codists

vue.js 多种方式安装

恒山其若陋兮

7月月更

【愚公系列】2022年7月 Go教学课程 014-运算符之算术运算符

愚公搬代码

7月月更

网络水军为何如此猖獗:揭秘背后灰色利益链

石头IT视角

Envoy负载均衡与限流设计

阿泽🧸

7月月更 Envoy负载均衡

zookeeper-集群leader选举

zarmnosaj

7月月更

【刷题记录】16. 最接近的三数之和

WangNing

7月月更

Starfish OS:以现实为纽带,打造元宇宙新范式

BlockChain先知

let关键字的特点

bo

前端 ES6 7月月更

一文解析Ansible配置管理文件

穿过生命散发芬芳

ansible 7月月更

王者荣耀商城异地多活架构设计(架构实战营 模块七作业)

Gor

如何分析并设计性能测试场景

老张

性能测试 需求分析

从去IOE到CIPU,中国云计算要走出自己的路径

B Impact

Docker安装Mycat中间件 | 实现主从&读写分离

宁在春

Docker 读写分离 mycat 7月月更

Spark Sql编译模块-词法、语法分析器Antlr4(一

飞哥

Okaleido tiger NFT即将登录Binance NFT平台,后市持续看好

西柚子

数据仓库和数据中台的关系

奔向架构师

数据仓库 7月月更

架构实战营模块 7 作业

Naoki

架构实战营

数据散列算法

技术小生

7月月更 散列算法

8 月亚马逊云科技培训与认证课程,精彩不容错过!

亚马逊云科技 (Amazon Web Services)

架构师 培训 认证

JavaScript小数点计算时失精问题

空城机

JavaScript 7月月更

更智能!AIRIOT加速煤炭行业节能减排升级

AIRIOT

低代码 物联网 低代码,项目开发

如何设计业务异地多活架构 - 作业

阿拉阿拉幽幽

Okaleido tiger NFT即将登录Binance NFT平台,后市持续看好

小哈区块

Java多线程之常见锁策略与CAS中的ABA问题

未见花闻

7月月更

王者荣耀商城异地多活架构

intelamd

第十届蓝桥杯大赛软件类省赛C/C++ 大学 A 组题解

KEY.L

7月月更

鸿蒙eTS版天气预报

坚果

开源 HarmonyOS OpenHarmony Open Harmony 7月月更

python小知识-如何判断一个对象为空值

AIWeker

Python python小知识 7月月更

Java中关于多线程的知识点

Java学术趴

7月日更

“Classic”与“Mockist”TDD,真的对立么?_研发效能_Mike Bria_InfoQ精选文章