可测试性系列之测试替身Test Double

简介: 在做测试的时候,通常会临时替身来协助我们完成测试。

在做测试的时候,通常会临时替身来协助我们完成测试。

image.png

因为不能被测试(SUT))在测试环境下依赖的组件正常使用。如外部系统。

当在一个不能使用真实依赖组件(depended-on component(DOC))的地方写test时,我们可以使用Test Double [1]

测试双

测试双重起来,有以下几种:

image.png

Martin Fowler在Mocks Aren't Stubs  [2]中翻译解释:

image.gifimage.png

Martin Fowler的解释还不是太明白,我又收集了更明白一点的解释[3]

Dummy - 只是为了满足 API 的虚假值

示例:如果您正在测试一个类的方法,该方法在构造函数中需要许多强制参数,而这对您的测试没有影响,那么您可以创建虚拟对象来创建类的新实例。

Fake - 创建一个类的测试实现,该类可能依赖于某些外部基础设施。(最好的做法是您的单元测试实际上并不与外部基础设施交互。)

示例:创建用于访问数据库的假实现,将其替换为内存中的集合。

Stub - 覆盖方法以返回硬编码值,也称为基于状态的

示例:您的测试类依赖于一个方法 calculate() 需要 5 分钟才能完成。您可以用返回硬编码值的存根替换它的实际实现,而不是等待 5 分钟;只花费一小部分时间。

Mock - 与 Stub 非常相似,但基于交互而不是基于状态。这意味着您不期望 Mock 返回一些值,而是假设进行方法调用的特定顺序。

示例:您正在测试一个用户注册类。调用 save 后,它应该调用 send ConfirmationEmail。

上面的已经很明白了,简单概括一下:

Dummy:主要是使用填充参数,以构造需要测试的对象

Fake:简单的模拟实现,如道,但只是空实现

Stub:相对来说点硬件编码返回值,那么很相似

模拟:相对状态验证更多是行为验证

读到这里每周一次大明白的方式,还有点模糊,要理解和理解了更清晰的区别,需要先了解生命周期

1、生命周期

测试都是由追踪追踪的阶段:

初始化(SetUp)、执行测试(Exercise)、验证结果(Verify)和受伤(Teardown)

2、验证方式

在验证阶段,通常有状态验证方式:验证与行为验证

状态验证:



//肯定会使用的assertassert
Equals(expected,actual);

行为验证:


//Mockito中的verifyverify
(mock, times(3)).do();

徐昊老师的描述:

万恶淫为首,论无处心,论心世上少人;过程不有趣,只看结果。结果验证

百为孝为先,论心无善,论贫家无孝子;看重过程,不看重结果。

所以我们鉴定淫棍总比鉴定孝子准确


测试策略是要保证的有效性,同时降低测试成本。

假的、存根的、模仿的,越来越低,同时也可靠低。

spy 与 mock 在使用时可能会区分出它们之间的区别,与 stub 的区别,定义看的。

徐昊老师引入过程的视角来进一步:

各个进程之间的存根就是假的,进程之间的存根就是假的。

结合以上的解释很明显,当使用数据库时,伪造一个内存数据库。

以过程划分:

进程间替身:dummy fakespy

进程内替身:stub mockspy

以验证方式划分:

严格来说,我们状态验证使用假存根,行为验证使用模拟。

dummy 和 spy 没有验证,dummy 是不能检验,spy 是测试检验。

spy可以按状态(比如比)也可以按行为(比如)验证。

spy 已经在行为验证和状态验证的边上。spy 是记录调用,对调用加上验证就是模拟

如果用记录来回复就是录播测试,比如你在两个系统间做了spy,把请求和结果播放出来,这样就相当于用spy的数据做的tub了。

请求把结果和目标结果做对比,实际拿spy数据做mock

spy本身只是取而不是一种数据内部数据验证技术,而是正常身份。

间谍是愚蠢的嘲笑

总结

中测试 Double 中的,Test Double 的形式有 dummy fake stub spy mock,以流程维度与验证方式维度能够更好地测试测试策略是要保证的同时,降低测试成本。地区分他们。

参考

[1] Test Double:  http: //xunitpatterns.com/Test%20Double.html

[2]  Mocks Aren't Stubs:  https

[3] :  //martinfowler.com/articles/mocksArentStubs.html收集了更清楚一点的解释:  https://code-examples .net/en/q/34c8d7


目录
相关文章
|
7月前
|
监控 前端开发 JavaScript
如何测试前端代码? 知道 BDD, TDD, Unit Test 么? 知道怎么测试你的前端工程么(mocha, sinon, jasmin, qUnit..)?
如何测试前端代码? 知道 BDD, TDD, Unit Test 么? 知道怎么测试你的前端工程么(mocha, sinon, jasmin, qUnit..)?
142 0
|
4月前
|
JavaScript 前端开发 测试技术
Vue.js开发者必看!Vue Test Utils携手端到端测试,打造无懈可击的应用体验,引领前端测试新风尚!
【8月更文挑战第30天】随着Vue.js的普及,构建可靠的Vue应用至关重要。测试不仅能确保应用质量,还能提升开发效率。Vue Test Utils作为官方测试库,方便进行单元测试,而结合端到端(E2E)测试,则能构建全面的测试体系,保障应用稳定性。本文将带你深入了解如何使用Vue Test Utils进行单元测试,通过具体示例展示如何测试组件行为;并通过Cypress进行E2E测试,确保整个应用流程的正确性。无论是单元测试还是E2E测试,都能显著提高Vue应用的质量,让你更加自信地交付高质量的应用。
79 0
|
4月前
|
Java 测试技术
Java SpringBoot Test 单元测试中包括多线程时,没跑完就结束了
Java SpringBoot Test 单元测试中包括多线程时,没跑完就结束了
75 0
|
5月前
|
Java 测试技术 程序员
测试气味Test Smells-整洁单元测试
摘要:本文讨论了代码中的“Code Smell”现象,即可能表明代码质量问题的模式。这些包括重复代码、过长函数、过大类、过长参数列表等。识别并重构Code Smell有助于提升代码质量和可维护性。在单元测试中,也有类似的“测试味道”问题,如无信息的测试名称、缺少arrange-act-assert结构、不恰当的变量名和重复使用以及杀虫剂效应。好的单元测试应有明确的命名、遵循arrange-act-assert模式、使用有意义的变量名,并避免重复测试同一情况,以提供有价值的错误信息。
|
6月前
|
Java
springboot Test 测试类中如何排除一个bean类
springboot Test 测试类中如何排除一个bean类
141 0
|
7月前
|
监控 前端开发 JavaScript
如何测试前端代码? 知道 BDD, TDD, Unit Test 么? 知道怎么测试你的前端工程么(mocha, sinon, jasmin, qUnit..)?
如何测试前端代码? 知道 BDD, TDD, Unit Test 么? 知道怎么测试你的前端工程么(mocha, sinon, jasmin, qUnit..)?
78 0
|
7月前
|
机器学习/深度学习 Shell 开发工具
利用 test命令的测试功能
【1月更文挑战第4天】利用 test命令的测试功能。
84 4
|
7月前
|
测试技术 Shell Android开发
随机测试 Monkey Test
随机测试 Monkey Test
175 0
|
7月前
|
缓存
pytest 运行测试函数报错的解决办法 TypeError: calling <function xxx> returned None, not a test
pytest 运行测试函数报错的解决办法 TypeError: calling <function xxx> returned None, not a test
357 0
|
测试技术 Go Cloud Native
Go test 单元测试用起来
单元测试,是指对软件中的最小可测试单元进行检查和验证