哪些功能在C中更容易测试?

时间:2014-07-24 06:59:35

标签: c unit-testing testing tdd

我用C编写代码。我一直在努力编写更多可测试的代码,但我有一点点 在决定编写真正有利于测试的纯函数时感到困惑 但在我的意见和写作功能中需要较小的功能和可读性 那会修改一些内部状态。

例如(所有状态变量都声明为静态,因此"私有"到我的模块):

您认为哪一项更具可测性:

int outer_API_bar()
{
   // Modify internal state
   internal_foo()
}

int internal_foo()
{
  // Do stuff

  if (internal_state_variable)
  {
     // Do some more stuff
     internal_state_variable = false;
  }
}

OR

int outer_API_bar()
{
   // Modify internal state

   internal_foo(internal_state_variable)

   // This could be another function if repeated many
   // times in the module
   if (internal_state_variable)
   {
      internal_state_variable = false;
   }
}

int internal_foo(bool arg)
{
  // Do stuff

  if (arg)
  {
     // Do some more stuff
  }
}

虽然第二个实现对于internal_foo来说更容易测试,因为它没有任何副作用,但它使得条形更加丑陋并且需要更小的功能,这使得读者很难跟随小片段,因为他必须不断地将注意力转移到不同的功能上。 / p>

您认为哪一个更好?与写OOPS代码相比,私有函数大多数时候都使用内部状态而不是纯粹的。通过在模拟对象实例上设置内部状态并测试私有函数来完成测试。我对于是否使用或是否将内部状态传递给私有函数而感到有点困惑,因为"可测试性"

3 个答案:

答案 0 :(得分:2)

每当编写自动化测试时,理想情况下我们都希望专注于测试该代码单元的规范,而不是实现(否则我们会创建在我们修改实现时会破坏的脆弱测试)。因此,对象内部发生的事情不应该与测试有关。

对于这个例子,我想建立一个测试:

  • 致电outer_API_bar
  • 执行测试
  • 使用其他可公开访问的函数和/或状态断言调用的正确行为(必须有某种方式执行此操作,就好像调用outer_API_bar的唯一副作用是此代码单元的内部,然后调用此函数不会以任何方式影响您的更广泛的应用程序,并且基本上是无用的。)

通过这种方式,您可以保留使用internal_foo等函数和internal_state_variable等变量作为实现细节的事实,您可以在重构代码时自由更改(即使用它)更具可读性,无需更改测试。

注意:此建议基于我个人的偏好,仅用于测试公共功能,而不是私有功能。你会发现很多关于这个话题的争论,其中一些人提出了很好的论据来测试私有函数是否有效。

答案 1 :(得分:0)

要非常具体地回答你的问题,纯粹的功能可以更加可测试'比任何其他类型的抽象。您可以包含的功能越纯,代码就越可测试。正如你所提到的,这可能是以可读性为代价的,我相信还有其他需要考虑的权衡因素。我的建议是瞄准更纯粹的功能,并寻找其他技术,让你可以补偿事物的可读性。

答案 2 :(得分:0)

两个片段都可以通过模拟测试。但是,第二个优点是,当调用internal_foo(bool arg)的模拟时,您还可以检查true的参数是否为falseinternal_foo()的预期值。在我看来,这将有助于进行更有意义的测试。

根据我们不知道的其他代码,不使用模拟测试可能会更困难。