Unit testing 什么时候测试不是单元测试?

Unit testing 什么时候测试不是单元测试?,unit-testing,Unit Testing,我正在寻找如下规则: 在以下情况下,测试不是单元测试: 它与数据库通信 它不能与其他测试并行运行 使用“环境”,如注册表或文件系统 还有什么?它没有断言,也不希望抛出异常。请参阅 在以下情况下,测试不是单元测试: 它与数据库通信 它通过网络进行通信 它涉及到文件系统 它不能与任何其他单元测试同时运行 您必须对您的环境做一些特殊的事情(例如编辑) 配置文件)来运行它 跨多个可能失败的单元实现测试不是单元测试 复杂的问题 假设我要编写一些业务逻辑,所有业务逻辑都需要通过某种形式的DAL访问数

我正在寻找如下规则:

在以下情况下,测试不是单元测试:

  • 它与数据库通信
  • 它不能与其他测试并行运行
  • 使用“环境”,如注册表或文件系统

还有什么?

它没有断言,也不希望抛出异常。

请参阅


在以下情况下,测试不是单元测试:

  • 它与数据库通信
  • 它通过网络进行通信
  • 它涉及到文件系统
  • 它不能与任何其他单元测试同时运行
  • 您必须对您的环境做一些特殊的事情(例如编辑) 配置文件)来运行它

跨多个可能失败的单元实现测试不是单元测试

复杂的问题

假设我要编写一些业务逻辑,所有业务逻辑都需要通过某种形式的DAL访问数据

假设为了测试的目的,我模拟了DAL单元(通过创建“模拟鸟”)

但这些模仿鸟当然是它们自己的额外单位。因此,即使在使用mock时,当我想对我的业务逻辑模块进行单元测试时,我似乎仍然会违反“不涉及其他单元”的想法

当然,众所周知,“为DAL创建模仿鸟”会使你的测试本身失效,因为你的模仿鸟在某些特定方面偏离了DAL

结论:完全不可能对以任何方式依赖于任何DAL的业务模块进行“真正的单元测试”,问号

腐蚀性:唯一可能的(“真正的”!)单元测试是DAL本身,问号


Corrolary of the Corrolary:考虑到“DAL”通常是ORM或某些DBMS的DML,并且考虑到这些产品通常作为“经验证的技术”购买,那么进行任何单元测试的附加值是什么?问号?

如果不测试单元,测试就不是单元测试

说真的,就这些

单元测试中的“单元”概念没有很好的定义,事实上,到目前为止我找到的最好的定义,实际上并不是一个定义,因为它是循环的:单元测试中的单元是可以单独测试的最小可能的东西

这给了您两个检查点:它是独立测试的吗?这是最小的可能吗

请注意,这两者都是上下文相关的。在一种情况下(比如说,整个对象)可能是最小的东西,在另一种情况下可能只是一个方法的一小部分。而在一种情况下被视为隔离的可能是在另一种情况下(例如,在内存管理的语言中,您永远不会与垃圾收集器隔离运行,而且大多数情况下这是不相关的,但有时可能不是)

对我来说,单元测试验证了隔离中的一条特定逻辑。也就是说,我采用一些逻辑,从其余部分中提取它(如果有必要,通过模拟依赖关系),并通过探索不同类型的可能控制流来测试该逻辑(整体的一个单元)

但另一方面…我们是否可以100%地说正确或不正确??不是要变得哲学化,而是——就像在他的岗位上一样:

这样的测试也不错。 通常它们值得一写,而且 可以写入单元测试线束中。 然而,重要的是能够 将它们与真正的单元测试分开,以便 我们可以保留一组测试 只要我们有足够的时间,我们就能跑得很快 变化

那么,为什么我不应该编写一个单元测试,通过访问测试文件夹中文件系统中的某个虚拟文件(如DeploymentItem允许的MS测试)来验证解析逻辑(例如xls文件)

当然,正如前面提到的,我们应该将这类测试与其他测试分开(可能在JUnit中的一个单独的测试套件中)。但我认为,如果一个人在那里感到舒适,他也应该编写这些测试……显然,然后总是要记住,单元测试应该只是单独测试一个部分


在我看来,最重要的是这些测试运行速度快,不需要太长的s.t。它们可以反复运行,而且非常频繁。

在确定测试是否为单元测试后,下一个问题是,它是单元测试吗

在以下情况下,测试不是单元测试:

  • 它一次测试多个事物(即,它测试两个事物如何协同工作),然后它就是一个集成测试
良好单元测试检查表:

  • 它们是自动化的
  • 它们是可重复的
  • 它们很容易实现
  • 一旦写好,它们将留作将来使用
  • 他们可以由任何人管理
  • 只需按一下按钮就可以运行它们
  • 他们跑得很快
还有一些最佳做法(没有特别的重要性顺序):

  • 测试应该与集成测试(速度较慢)分开,以便尽可能快地运行它们
  • 它们不应该包含太多的逻辑(最好没有控制结构)
  • 每个测试应该只测试一件事情(因此,它们应该只包含一个断言)
  • 断言中使用的预期值应该是硬编码的,而不是在测试运行时计算的
  • 外部依赖项(文件系统、时间、内存等)应替换为存根
  • 测试应在测试关闭时重新创建初始状态
  • 在断言中,最好使用“包含…”策略,而不是“严格相等…”策略(即,我们期望集合中的某些值、字符串中的某些字符等)

这是我从Roy Osherove的书中提取的知识的一部分-

+1:棘手的一个,我认为如果您没有注意到这一点,您的IDE会给您一个错误或至少一个警告-