我用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代码相比,私有函数大多数时候都使用内部状态而不是纯粹的。通过在模拟对象实例上设置内部状态并测试私有函数来完成测试。我对于是否使用或是否将内部状态传递给私有函数而感到有点困惑,因为"可测试性"
答案 0 :(得分:2)
每当编写自动化测试时,理想情况下我们都希望专注于测试该代码单元的规范,而不是实现(否则我们会创建在我们修改实现时会破坏的脆弱测试)。因此,对象内部发生的事情不应该与测试有关。
对于这个例子,我想建立一个测试:
outer_API_bar
。outer_API_bar
的唯一副作用是此代码单元的内部,然后调用此函数不会以任何方式影响您的更广泛的应用程序,并且基本上是无用的。)通过这种方式,您可以保留使用internal_foo
等函数和internal_state_variable
等变量作为实现细节的事实,您可以在重构代码时自由更改(即使用它)更具可读性,无需更改测试。
注意:此建议基于我个人的偏好,仅用于测试公共功能,而不是私有功能。你会发现很多关于这个话题的争论,其中一些人提出了很好的论据来测试私有函数是否有效。
答案 1 :(得分:0)
要非常具体地回答你的问题,纯粹的功能可以更加可测试'比任何其他类型的抽象。您可以包含的功能越纯,代码就越可测试。正如你所提到的,这可能是以可读性为代价的,我相信还有其他需要考虑的权衡因素。我的建议是瞄准更纯粹的功能,并寻找其他技术,让你可以补偿事物的可读性。
答案 2 :(得分:0)
两个片段都可以通过模拟测试。但是,第二个优点是,当调用internal_foo(bool arg)
的模拟时,您还可以检查true
的参数是否为false
或internal_foo()
的预期值。在我看来,这将有助于进行更有意义的测试。
根据我们不知道的其他代码,不使用模拟测试可能会更困难。