TDD:为什么让应用程序代码知道它正在测试而不是运行可能是错误的?

TDD:为什么让应用程序代码知道它正在测试而不是运行可能是错误的?,第1张

TDD:为什么让应用程序代码知道它正在测试而不是运行可能是错误的?

我将这个答案分为两部分。首先,我将分享我对Brian答案的看法,然后我将分享一些有关如何有效测试的提示。

布赖恩答案的解释

Brian暗示了两个关键思想。我将分别针对每个人。

理念1:生产代码不应依赖于测试

您的代码应以与测试无关的方式编写。

生产的代码应该 依赖于测试。应该是相反的。

原因有很多:

  1. 更改测试 不会更改 代码 的行为
  2. 您的生产代码可以 独立 于测试代码进行编译和 部署
  3. 更新测试时, 无需重新编译 您的代码。
  4. 由于未运行测试代码而产生了意外的副作用,因此您的生产代码 可能不会失败

注意: 任何体面的编译器都会删除测试代码。尽管我认为这不是设计/测试系统不佳的借口。

想法2:您应该测试抽象而不是实现

无论您在什么环境中进行测试,都应尽可能接近真实世界。

听起来 像布莱恩可能在他的回答中这种想法在暗示。与最后一个想法不同,这个想法尚未得到普遍认可,因此请带上一粒盐。

通过测试抽象,您可以提高对测试单元的尊重程度。您同意 不会 与它的内部混为一谈并监视其内部状态。

为什么在测试期间我不应该监视对象的状态?

通过监视对象的内部,将导致以下问题:

  1. 您的测试将使 您与 单元 的特定实现联系在一起

例如,
是否要将类更改为使用其他排序算法?太糟糕了,因为您断言 必须 调用该

quicksort
函数,所以测试将失败。 __

  1. 您将 破坏封装

通过测试对象的内部状态,您将很容易放松该对象所具有的某些隐私。这将意味着您的更多 生产 代码也将提高对对象的可见性。

通过放松对象的封装,您正在诱使其他生产代码也依赖它。这不仅可以将您的 测试 绑定到特定的实现,而且还可以绑定整个系统本身。您 希望这种情况发生。

那我怎么知道这个班上课了?

测试所调用方法的前提条件和条件前提/结果。如果您需要更复杂的测试,请看我写的关于 模拟 和依赖注入的最后一节。

迷你笔记

只要* 您的生产代码与测试无关,我认为

if (TEST_MODE)
在main方法中添加一个并不一定很糟糕。 *

例如:

public class Startup {    private static final boolean TEST_MODE = false;    public static void main(String[] args) {        if (TEST_MODE) { TestSuite testSuite = new TestSuite(); testSuite.execute();        } else { Main main = new Main(); main.execute();        }    }}

但是,如果您的其他类 知道 它们正在测试模式下运行,则将成为一个问题。如果您拥有

if(TEST_MODE)
所有生产代码,那么您就可以迎接上面提到的问题。

显然,在Java中,您可以使用诸如JUnit或TestNG之类的东西来代替它,但是我只是想分享我对该

if (TEST_MODE)
想法的看法。

如何有效测试

这是一个非常大的主题,因此我将在答案的这一部分中简短介绍。

  • 与其监视内部状态, 不如使用模拟和依赖注入

使用模拟,您可以断言您已注入的模拟方法已被调用。更好的是,依赖项注入将使您的类对所注入内容的实现的依赖关系反转。这意味着您可以交换事物的不同实现,而不必担心。

这完全消除了在类内部闲逛的需要。


如果我强烈推荐阅读一本书,那就是 Jeff Langr 撰写的《 具有测试驱动开发现代C ++编程》 。这可能是我用过的最好的TDD资源。
__

尽管标题中有C ++,但它的主要重点肯定是TDD。本书的开头讨论了这些示例应如何应用于所有(相似)语言。鲍勃叔叔甚至在前言中指出:

您需要成为C 程序员才能理解吗?当然不会。C
代码非常简洁,编写得井井有条,概念非常清晰,任何Java,C#,C甚至Ruby程序员都不会遇到麻烦。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5498700.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存