【问题标题】:Should test cases chain? [closed]测试用例应该链接吗? [关闭]
【发布时间】:2019-10-03 14:58:56
【问题描述】:

假设我想要测试以下通用工作流程:

CreateObject --> AddItemsToObject --> SaveObject --> ChangeObjectToFirstState --> ChangeObjectToSecondDependentOnBeingInFirstState --> 等等...

我应该:

A) 为这些状态中的每一个完整编写一个测试用例 - IE,CreateObject 将测试对象是否正确创建,AddItemsToObject 将使用 CreateObject 使用的代码的副本,然后测试是否向对象添加项目处理得当,SaveObject 会使用 AddItemsToObject 使用的代码的副本,然后将对象保存到数据库并测试是否正确保存等...

B) 为 CreateObject 编写测试用例,成功返回一个创建的对象,然后 AddItemsToObject 将其用作要添加项目的对象,然后 SaveObject 将其用作要保存的对象,等等……

C) 不必费心将链的每个步骤拆分为单独的测试用例,只需为每个完整的链编写一个测试用例

我已尝试搜索可能无法回答此问题的其他示例 - 如果已彻底回答,请链接我相应的问题 :)

* 编辑 *

重新措辞一下,让它更像一个问题:

是否有任何具体原因使用基于链的方法为工作流编写测试用例?

换句话说,对于多阶段工作流,在实现测试用例时,是否有任何特定原因首先调用测试用例以将对象从状态#2 推进到状态#3用于将对象从状态 #3 推进到状态 #4?

【问题讨论】:

  • 您是在描述调用堆栈还是工作流?
  • 这是一个基于意见的问题,考虑到我会选择 A,并且可能还会为每个完整的链选择一个测试用例。 B 的问题在于,如果出现问题而测试失败,则必须遍历整个链条才能了解原因。
  • @bradbury9,不完全确定你的意思 - 我正在尝试为状态机编写测试用例,基本上可以通过流程图来描述。我不是在谈论为特定状态编写测试用例。相反,我问的是,例如,测试第四个状态是否应该首先调用将其带到第三个状态的测试用例(反过来,第二个状态也一样,等等......),或者是否测试第四状态应该包含将其带到第四状态的代码。

标签: c# unit-testing chaining


【解决方案1】:

TL;DR - 不同级别测试的组合,单元(案例 A)-> 集成(案例 B)是理想的方法。

我经常看到,将测试添加到代码库更像是一个旅程,而不是一个单一的工作项。需要考虑许多变量,例如分配给测试的时间、系统的关键性、代码的复杂性等等。

就您的示例而言,从开发人员的角度来看,编写广泛的集成测试(案例 C)几乎总是更简单、更快捷。然而,正如所指出的,这种方法存在缺陷。举几个例子,1)如果失败,调试起来会更困难,2)如果你的每个 n 函数都有,例如,2个代码路径,你需要 2^n覆盖所有路径的测试用例。也就是说,集成/系统测试总比没有测试好。根据我的经验,在测试现有/遗留代码库时,它们是最有价值的代码。

另一方面,如果您有时间,为特定功能(案例 A)编写单元测试是补充您的测试基础的绝佳方式。在这种情况下,使用上面列出的变量,您只需要 2*n 测试来覆盖所有路径,并且一次测试中的失败将识别出一个较小的用于调试的向量。一个好的模式是使用像 Moq 这样的 DI 框架来隔离每个单独组件的逻辑。

Here's a more thorough conversation on unit vs. integration tests.

案例 B 也不一定是坏方法;它本质上是一种集成测试形式,您可以在其中更深入地了解问题发生的位置。同样,这些是您需要在项目上下文中做出的决定,同时考虑到整个工作流程上下文中每个单独功能的复杂性等因素。

【讨论】:

  • 嘿@chill94,感谢您的见解。在案例 A 和案例 B 之间,您推荐哪个?就个人而言,感觉案例 B 是更好的选择,但实际上我还没有找到任何真正推荐它的文章或线程,这就是我问的原因 - 通常如果没有人问过问题,这意味着要么 A ) 答案是如此明显,以至于没有人费心去问,或者 B) 我没有正确搜索:)
  • @KiranRamaswamy - 编辑:我误读了这个问题 - 以下比较了 A 和 C。让我添加一条新评论来回答您的 实际 问题。 ----- 我只是添加了一个总结点。理想情况下,你会拥有两者。查看链接的文章以了解更多信息。它们各有优缺点,而且都需要时间来写作。如果时间是一个主要因素,我会选择案例 C,因为这将决定该功能是否有效(基本上)。
  • 使用我上面评论中的许多观点,如果时间是一个主要因素,案例 B 将是可行的方法,因为它与案例 C 有很多相似之处。你不需要提取依赖项以进行可靠的单元测试。话虽如此,如果你有时间,编写可靠的、可测试代码(以及相应的单元测试 - 案例 A)始终是一项巨大的投资。但同样,我不能提出建议,因为这在实践中是一个复杂的决定。你现在能做的最好的事情就是继续阅读和了解测试(正是你正在做的事情!),以继续做出明智的决定
  • 我通读了您链接的那个 stackoverflow 线程,它确实给了我见解,但它并没有真正回答我的具体问题。在我的示例中,案例 A 和案例 B 都是集成测试——它们不是单元测试,因为例如,状态 4 的测试用例不是从状态 3 中的对象开始的。感觉像案例 B 的原因是更好的方法是因为在案例 A 中,有很多代码被重复——状态 4 的测试用例本质上重复了状态 3 测试中已经编写的所有代码。
猜你喜欢
  • 2015-11-12
  • 2014-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-16
  • 2020-12-30
相关资源
最近更新 更多