如果一个方法调用另一个方法,是单元测试还是集成测试?

If a method calls another method, is it a unit test or integration test?

我是 tdd 概念的初学者,所以我的问题是,如果我有一个调用另一个方法的方法,听起来很简单,它是单元测试还是集成测试?如果它是一个集成测试,那只是因为我的方法调用了另一个方法并且方法之间有一个 "integration"?

if I have a method that calls another method, as simple as it may sound, it is a unit test or a integration test?

遗憾的是,这将取决于您使用的 "unit test" 和 "integration test" 谁的定义。二十年前,当这些定义是由软件测试领域的专家推动的时候,这个问题更容易回答。

但是 TDD 发生了;肯特·贝克 (Kent Beck) 对他的定义并没有特别严格的规定,于是一堆新想法开始涌现。

即使在 TDD 的上下文中,对于 "unit test" 的含义也存在细微的分歧。例如,一个重要的想法是测试不应该对它们的顺序敏感运行;每个单独的测试都包含正确测量系统所需的所有设置和拆卸。另一个是两个测试 运行ning 在同一进程中同时进行,不应相互干扰;所以没有共享可变状态..

这里的共同主题是 test 受到约束; "unit test" 将描述具有一组特定属性的测试。

一个不同的想法来自于观察,如果没有非常仔细的设计,大型测试在项目的整个生命周期中都是脆弱的。如果 测试对象 的可观察行为反过来取决于许多可能改变的不同决定,那么脆性测试是一个常见的结果。

因此出现了一种不同的约束,表明测试对象应该很小 - "unit test" 是这样一种情况,其中测试对象的行为仅取决于可能会改变的少量决定.

更令人困惑的是,Beck 和其他人曾经成功使用的仪式在不同时期以 "Test First Development"、"Test Driven Development"、"Test Driven Design" 进行营销——混淆动机。是目的test,还是目的design

据我所知,每个人都同意不委托其任何工作的方法是单元测试的好主题。

此外,每个人都同意将其工作委托给稳定的协作者(例如标准库)的方法是单元测试的好主题。

但是,当我们将不使用协作者的设计替换为使用不稳定协作者的设计时,分歧就开始了(将工作委托给其他方法,尤其是当它们处于不同的 "classes" 时)。

如果我们改变设计让不稳定的部分分担工作,这还是单元测试吗?我相当确定 Beck 会同意,Freeman 和 Pryce 也会同意。我不太确定@JBrains;参见 Integrated Tests are a Scam。有些人已经完成了自己的实验,并找到了适合自己的工作;其他人有他们的解释 "best practices" 由他们喜爱的专家描述。

简而言之:一团糟。

我能提供的最佳答案是,与其担心我们用于不同风格测试的 标签 ,不如专注于有趣的 属性集,确保测试具有这些属性并使这些属性与其用途保持一致所需的约束。

例如,如果您要 运行 在开发会话期间进行多次测试,作为及早发现错误的机制,那么您可能希望这些测试速度快,并且独立于什么发生在你自己以外的环境中。要获得这些属性,您可能需要避免测试中的网络流量,甚至可能 I/O —— 在内存中执行 "everything" 会快得多(并且让您暴露在某些风险中需要通过其他方式进行管理)。

另一个答案真的很有帮助,但让我们补充一下这个想法:

if I have a method that calls another method

它从那里开始。如果被调用的 other 方法存在于您的 "unit under test" 中,那么我会认为它是一个单元测试。

如果该方法位于 "another" 单元中(不是 "under test",而是 "dependency"),则取决于:如果您 mock/stub 另一个单元,我认为您仍在 运行 进行单元测试。但有人甚至可以声称:当另一个单元可以直接调用而无需存根时,您仍然可以 运行 对该初始部分进行单元测试。

换句话说,你看看目的,以及 "unit" 环绕的 "definition":当我编写一套测试时,所有的 public 方法都有效一个 Java class,那么这些很可能是单元测试。也许我必须存根依赖项,也许我做了一个很棒的设计并且依赖单元可以在没有变通方法的情况下使用。

"next" 级别不是集成测试。这是 "function" 测试。你不用看 "class X does this or that",而是问 "does feature Y work",不用担心你是否只需要 class X 或其他 5 个 classes。您关心更大的(端到端)功能,而不是单个 "unit" 的代码组织。

"next"级别,即集成测试。在我的书中,这些是关于确保一整套 features/functions 聚集在一起,并且每个人都在做它应该做的事情,并一定程度地关注 stubbed/mocked/ignored 在较低 unit/function 测试事物的一面。

我会更进一步,尝试忘记 "unit"、"integration"、"behaviour" 或 "acceptance" 测试,而是将所有测试分成两组

  • 快速测试
  • 慢速测试
    • 访问外部资源(文件系统、数据库、Web 服务等)时
    • 配置非常复杂的测试用例

通过模拟外部资源或非常复杂的依赖关系,您可以在 "Fast" 类别中移动一些测试用例,并向开发人员提供更快的反馈。

我会尝试尽可能少地模拟,只要测试执行得足够快以 运行 在每次更改代码后进行测试。

然后"unit"将成为一个行为单元,它将测试应用程序的行为并尽可能使应用程序保持"black box"。

Integration Testing就是集成后测试不同的模块 单元测试意味着将模块作为一个完整的单元进行测试。 在我看来,我们称它为单元测试和集成测试