【问题标题】:Unit testing: Is it bad practice to call public methods (for setup) while testing another method?单元测试:在测试另一种方法时调用公共方法(用于设置)是不好的做法吗?
【发布时间】:2016-03-03 23:41:41
【问题描述】:

这是一个普遍的问题,但知道我正在使用一个封装了 RPC 样式(远程过程调用)控制器的系统可能会有所帮助,这正是我正在测试的。它包含更改此控制器内部状态的公共方法。可以使用公共方法读取此控制器的状态。

这个类中的两个方法是:

  • CreateProgramSet(...),创建“程序集”(更改 RPC 控制器的内部状态)和
  • GetStatus(),检索此 RPC 控制器的状态,包括使用 CreateProgramSet(...) 创建的程序集。

为了测试GetStatus(),我使用一些硬编码参数调用CreateProgramSet(...)(用于设置),然后根据硬编码值测试GetStatus() 的结果。

为了测试CreateProgramSet(...),我的做法完全相同,只是在这种情况下GetStatus() 用于验证CreateProgramSet(...) 是否正确运行。

我在这个测试场景中看到的问题是,现在两个测试都耦合到这两个方法,所以如果GetStatus() 发生变化,两个测试都可能失败。如果CreateProgramSet(...) 更改,则两个测试都可能失败。但最重要的是,如果两种方法都以正确的方式改变(不知道彼此的改变),两种测试都可能因错误的原因通过。这显然是不受欢迎的情况。我从这个问题中看到的唯一方法是测试类的内部,但这在测试中是不受欢迎的。

我发现的大多数示例都处理返回值的方法,例如“添加”方法或不需要设置的极其简单的方法。实际上,许多类变得足够复杂,需要设置来测试类的各个部分。对于可以处于多个状态的类尤其如此。而如果一个类不存储状态,还不如让它成为一个静态类。此外,我发现大多数示例都是数据测试输出而不是状态变化。难道我做错了什么?对我来说,这个问题指向代码异味,但我似乎无法弄清楚我做错了什么。

这个问题与语言无关,但如果它有所作为,我正在使用 C# 和 NUnit。

【问题讨论】:

  • 太久没有阅读:如果 2 个测试具有相同的前提条件,您可能可以配置您的测试框架,使其在执行测试之前执行前提条件。对于 JUnit,它是 @Before
  • @Tunaki 这不是问题所要问的......它询问将两个公共方法耦合到同一个测试是否是不好的做法,即使其中一个方法未在测试中,但仅用于设置用于测试其他方法。
  • 这就是为什么我说:“设置”是一个先决条件。因此,应该以专门用于设置的专用方法将其分开。并让测试框架在每次测试之前调用该设置方法。
  • 无论如何,如果设置失败,测试仍然会因为错误的原因失败。
  • 不:设置方法不是测试本身的一部分。如果设置失败,测试甚至不会运行。

标签: java c# unit-testing testing nunit


【解决方案1】:

单元测试不是关于测试方法,而是关于测试场景。

您拿起一个单元,对其进行设置,然后检查它的行为是否符合预期。不要过多地考虑方法:它不是过程式编程,而是 OOP——您应该测试您的单元是否通过了最可能的用例场景、一些极端情况,仅此而已。

附:如果您描述的是一种不好的做法,则无法测试有状态类:您总是使用一些方法调用来设置它,并使用其他一些方法调用进行验证,这意味着有缺陷的方法的幸运(或不幸)组合有时可能会导致正确的结果(但这种情况发生的频率如何?)。

【讨论】:

  • >P.S.如果您描述的是一种不好的做法,那么就无法测试有状态的类——这正是我的观点。单元测试说要单独测试场景,但是当您需要使用公共接口来检查公共接口的其他部分时,我们会远离这种隔离,不是吗?
  • 与其他场景隔离,而不是与其他方法隔离
  • >但是这种情况多久发生一次? -- 不经常,但你会认为单元测试的理论不会允许这种情况发生,如果正确完成。
  • 还有讽刺意味的是,维基百科上的“正式验证”文章“需要额外的引用来验证”。让我笑了。
  • 是的,这是一个很好的 - 没有注意到:)。还有一篇关于 "mission critical" 含义的文章 - 如果您不了解它,可能有助于了解这个概念。
猜你喜欢
  • 1970-01-01
  • 2010-11-25
  • 1970-01-01
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-01
  • 1970-01-01
  • 2016-12-30
相关资源
最近更新 更多