Unit testing 是否存在单元测试无法发现的逻辑/流错误类型?

Unit testing 是否存在单元测试无法发现的逻辑/流错误类型?,unit-testing,language-agnostic,defects,Unit Testing,Language Agnostic,Defects,假设我已经定义了合同和明确的需求(包括输入范围、边界值等),并且单元测试验证了所有这些条件,那么当我把这些单元放在一起时,还会有集成错误吗?我现在不考虑外部服务。 我已将以下内容视为集成错误的一个示例,但我认为这只是单元级缺少的测试: class Engine { int RPM; void SetRPMtoZero() { RPM=0; } } class Display { CalculateAverage(Engine e) { if

假设我已经定义了合同和明确的需求(包括输入范围、边界值等),并且单元测试验证了所有这些条件,那么当我把这些单元放在一起时,还会有集成错误吗?我现在不考虑外部服务。 我已将以下内容视为集成错误的一个示例,但我认为这只是单元级缺少的测试:

class Engine
{
   int RPM;

   void SetRPMtoZero()
   {
      RPM=0;
   }
}

class Display
{
  CalculateAverage(Engine e)
  {
    if (e.IsRunning)
    {
      int X=smth/e.RPM;  //could be division by 0
    }
  }
}

class IntegratingClass
{
  Engine e
  Display d..

  ...

  e.SetRPMtoZero();
  d.CalculateAverage(e);

  //this sequence would lead to the division by zero

}
我不认为这显示了一个集成错误-CalculateAverage只是缺少对RPM的检查=0


实际上是否存在单元测试无法发现的逻辑错误(或控制流)

有趣的问题。一方面,这很愚蠢。显然,一定有某种逻辑无法通过单元测试发现,否则单元测试就是Delphi的预言

我认为这里重要的哲学思考是涌现复杂性的概念。许多思想家过去都指出了这一点。摩尔定律可能是最好的例子[晶体管的复杂度大约每2.5年翻一番]。但这是一个总的原则


因此,将涌现复杂性的规律抽象到软件测试中:5个软件单元分别是更复杂、相等还是更少复杂,还是一起更复杂?当你这样说的时候,很明显,5个单元一起工作一定比单独的单元更复杂。这被称为“超过其各部分之和”,是系统的一般规则

我同意您的观点,这个示例是关于类显示缺少单元测试的

然而,这个例子的作者可能想指出,单元之间的耦合可以更强 超出预期或合同中描述的。此外,这个例子已经清楚地表明,在集成级别上 在单元测试级别上,事情可能会不同于预期(可能不是为了 SetRPMtoZero方法在CalculateAverage方法之前调用)。 通常在单元测试级别上看不到这一点,除非您有世界上最好的规范

那么,在集成单元时,您可能还会遇到什么(同时,这也是单元测试无法告诉您的):

  • 即使在集成测试的第一阶段,集成本身(例如,如果我们谈论像c++这样的语言,将单元链接在一起), 如果接口在一个单元中更改,但在另一个单元中未相应调整,则可能会失败
  • 如果单元使用公共资源(如文件、内存),则资源的保留/释放可能会导致阻塞状态或数据损坏
  • 如果你用100%的篇幅覆盖了一个单元测试的源代码,这并不意味着所有的代码都是必需的。论整合 您可能会意识到,当将单元组合在一起时,有很多代码甚至无法达到。这可以帮助你发现, 代码的哪些部分可能是“死代码”
  • 性能限制或资源限制(如内存有限)
  • 对合同的误解或合同执行中的错误

单元测试是为了测试其他代码而编写的代码。那么,测试其他代码的代码会错过什么吗?当然可以。测试是关于最小化风险,而不是消除风险。这个问题及其答案在很大程度上取决于测试内容的情况,没有通用答案。