当前位置:网站首页>本周小贴士#135:测试约定而不是实现
本周小贴士#135:测试约定而不是实现
2022-07-07 15:39:00 【-飞鹤-】
作为TotW#135最初发表于2017年6月5日
由James Dennett创作
“如果你有一个真正的朋友,那么你拥有的不仅仅是你所拥有的”——托马斯·富勒
C++有一个使用公有的,保护的,私有的和友元的详细访问控制机制。测试代码有它自己使用这些装置的规则,GoogleTest使用它的FRIEND_TEST宏来扩充它们。使用FRIEND_TEST应该是最后的手段,而不是优先选项。
测试约定
我们编写测试来发现组件约定实现中的错误,或者让我们有足够的信心相信这里没有此类错误。在使用测试驱动开发(TDD)时,我们还编写测试来帮助我们设计约定。依赖于组件未指定内容的测试很脆弱,即便生产代码正常工作,也容易报告失败。
优先通过组件的公共接口进行测试。更通用地说,测试应该验证组件的约定,并且与任何其他客户端一样,不应该做出超过保证的假设。
提供来自测试访问的技术
许多技术能够被用来允许测试代码完成其工作的必要访问。这里列举出一些,大致从好到坏进行排列。
为测试增加公共API
在通过最小接口进行测试时,有时很难获得足够的覆盖率。如果您的组件正在实现由基类指定的非常狭窄的接口(例如,只有一个 ProcessItem 虚函数的接口)并且从仅使用该接口的测试中获得足够的信心是不切实际的,请考虑创建一个新的、可测试的组件,其中包含实施细节。那么包含虚函数的类可以非常简单,只需要最少的测试。 BUILD 可见性可用于限制您的实现类的使用(如果需要并且您的构建系统支持它)。
如果测试仅依赖于一两个私有函数,请考虑将这些函数作为公共接口的一部分。这还不错:无论如何,您都需要它们具有清晰记录的接口,并且其他客户端(不仅仅是测试)可能会发现它们很有用。如果在考虑之后,您决定一个函数确实只用于测试,那么它应该被记录下来,并且可能以 ForTesting 后缀命名。
使用对等体来避免暴露实现
如果测试仍然需要访问私有实现细节,请创建一个测试对等体(有时称为测试配对)。 测试对等体是被测类的友元类,通常在 _test.cc 文件中定义(尽管有些人更喜欢将其定义在与友元类相同的文件中),并用于提供对待测试类的受控访问的测试代码。 测试对等体将不能存在于匿名命名空间中,因为它的确切名称需要与朋友声明相匹配,但测试代码的其余部分可以像往常一样位于匿名命名空间中。 测试对等类的名称通常以 Peer 结尾。
最后的手段:使用FRIEND_TEST
虽然在老代码中很常见,但是FRIEND_TEST不应该被用在新代码中。它引入了反向耦合,使生产代码头文件依赖于相关单元测试的细节。它强制测试从匿名命名空间中移出。每个FRIEND_TEST都授予一个测试函数不受约束地访问待测类;在长的测试函数中,很难发现测试在哪里修改了待测类的状态。它需要使用由GoogleTest提供的一个不常见的头文件去包含在生产代码中,然而几乎所有的GoogleTest仅用于测试。最后它的扩展性很差,在添加新测试时需要将新的FRIEND_TEST添加到生产的头文件中。在实践中,这通常会导致头文件拥有冗长的FRINED_TEST块。
不要让整个测试装置成为友元
强烈建议不要让整个测试装置成为待测类(带有友元类MyClassTest)的友元。与上述选项比较,它允许整个测试装置(但不是测试本身,它们是测试装置的子类)不受限并且无注释地访问待测类的每个成员,这意味着测试代码的读者没有测试何时打破封装的可见的线索。它还强迫测试装置位于匿名命名空间之外。与友元装置相比,测试对等体使代码更加自我注释化,并且代码作者只需要花费一点额外的工作。
建议摘要
- 优先测试组件的客户端接口,并且保证测试独立于私有实现的细节。
- 如果客户端接口不满足彻底运行待测单元,则将可测试的,可能仅用于测试的子组件分解出来。
- 有时添加到公共接口以使组件可测试是合理的。
- 如有必要,请使用测试对等体而不是使用 FRIEND_TEST 从测试中访问私有成员。
- 不要与整个测试装成为友元。 使用上述更有针对性的方法之一。
边栏推荐
- LeetCode 497(C#)
- LeetCode 1626. The best team without contradiction
- 状态模式 - Unity(有限状态机)
- The computer cannot add a domain, and the Ping domain name is displayed as the public IP. What is the problem? How to solve it?
- 【饭谈】Web3.0到来后,测试人员该何去何从?(十条预言和建议)
- 麒麟信安中标国网新一代调度项目!
- [video / audio data processing] Shanghai daoning brings you elecard download, trial and tutorial
- 专精特新软件开发类企业实力指数发布,麒麟信安荣誉登榜
- Sator推出Web3游戏“Satorspace” ,并上线Huobi
- 麒麟信安操作系统衍生产品解决方案 | 存储多路径管理系统,有效提高数据传输可靠性
猜你喜欢

Matplotlib绘图界面设置

NeRF:DeepFake的最终替代者?

【TPM2.0原理及应用指南】 5、7、8章
Share the latest high-frequency Android interview questions, and take you to explore the Android event distribution mechanism

User defined view essential knowledge, Android R & D post must ask 30+ advanced interview questions

The process of creating custom controls in QT to encapsulating them into toolbars (II): encapsulating custom controls into toolbars

鲲鹏开发者峰会2022 | 麒麟信安携手鲲鹏共筑计算产业新生态

Test case management tool recommendation

【网络攻防原理与技术】第5章:拒绝服务攻击

麒麟信安操作系统衍生产品解决方案 | 存储多路径管理系统,有效提高数据传输可靠性
随机推荐
LeetCode 1696. Jumping game VI daily question
【网络攻防原理与技术】第6章:特洛伊木马
大笨钟(Lua)
字符串 - string(Lua)
Leetcode brush questions day49
LeetCode 890(C#)
责任链模式 - Unity
Reflections on "product managers must read: five classic innovative thinking models"
PLC:自动纠正数据集噪声,来洗洗数据集吧 | ICLR 2021 Spotlight
电脑无法加域,ping域名显示为公网IP,这是什么问题?怎么解决?
redis主从、哨兵主备切换搭建一步一步图解实现
Share the latest high-frequency Android interview questions, and take you to explore the Android event distribution mechanism
[Seaborn] combination chart: facetgrid, jointgrid, pairgrid
Siggraph 2022 best technical paper award comes out! Chen Baoquan team of Peking University was nominated for honorary nomination
让保险更“保险”!麒麟信安一云多芯云桌面中标中国人寿, 助力金融保险信息技术创新发展
With the latest Alibaba P7 technology system, mom doesn't have to worry about me looking for a job anymore
Skimage learning (3) -- gamma and log contrast adjustment, histogram equalization, coloring gray images
centos7安装mysql笔记
Sator launched Web3 game "satorspace" and launched hoobi
Biped robot controlled by Arduino