如何对使用其他单元测试函数的函数进行单元测试?
如何测试使用已经测试过的其他函数编写的函数?说一个函数f
已经有了单元测试,这样我们就可以相信它的行为如我们所期望的那样。这是写在条款f
另一个功能g
的一个简单的例子:如何对使用其他单元测试函数的函数进行单元测试?
def g(a,b):
return f(1/b, a)
是g
所做的唯一工作是它的参数一些操作和将它们传递给f
正确的方式(在一个更复杂的例子中,我们可能会有更多详细的参数操作)。由于f
已经过测试,因此我需要使用g
进行测试的唯一一件事是我正确操作了参数,并且在将它们传递给f
时我没有混淆它们。我看到两种方法:
- 经典方法:手工查找((arguments,expected_results)对并编写像
g(1,2) == 3
这样的测试。采用这种方法,我会暗中重新测试f
,因为我必须手工找到f(1/b, a)
的预期结果。另外,这可能是计算f(1/b,a)对于任何微不足道的b(例如f
被测试的值更容易)很难手工完成。 - 在测试中重复使用
f
:编写测试如assert g(1,2) == f(1/2, 1)
。但是这看起来很像重写函数g
的主体,其实参由实际值替换。因此,我可能会在函数体和测试中两次出现相同的错误。
什么是测试g
的最佳方式?除了这两个还有别的方法吗?
如何测试使用已经测试过的其他函数编写的函数?
像任何其他功能一样。
如果f
已经过测试,那么您不应该担心它会导致问题。如果确实会导致问题,您没有正确测试f
。
我看到两种方法
与第一种方法去。
你说“我们可能有更多详细的操作”,所以第二种方法是不可能的。
更何况,如果你不小心弄乱了表达的rhs怎么办?
assert g(1, 2) == f(1/1, 2)
通过这种方法,我会暗中重新测试
f
你是不是重新测试f
,您使用的是执行内部测试功能。
这只是一个问题,如果f
是错误的。你不介意在测试中使用标准库中的行为,那么如果你说它已经过测试,那么f
会有什么不同?
我需要
g
测试的唯一事情是我正确操作的参数和它们传递给f
时,我没有把它们混合起来的第二条语句是有点过度。混合参数通常在黑盒测试时显示:如果g
没有按正确的顺序将参数传递给f
,那么结果应该不像预期的那样/您应该预期结果无效。
如果你的结果是正确的,但参数混淆了,那么你的断言不是很细致,你应该让它们更加详细。下面是一个糟糕的测试的例子。虽然断言是正确的,这两个看似相同的黑匣子感(他们显然都没有):
def mod(a,b):
return a%b
assert mod(10, 4) == 2
assert mod(10, 9) == 1
def divide(a,b):
return a/b
assert divide(10, 4) == 2
assert divide(10, 9) == 1
混合起来的论点可能是有问题的,但如果你的测试中,它会只打了生产不详细。如果你有g
问题,您可能想分解的突变行为:
def g(a,b):
return f(mutateB(b), mutateA(a))
然后独立测试mutate
功能,确保他们的工作。
另一种方法是存根f
函数i.d.提供在测试中使用的f
的替代实现,其责任是返回提供的输入的定义值。这将允许在日照下测试g
。
这是一个好主意,当然会让测试更安全。但我不确定很容易找到一个常用的函数的替代实现。 –
@VinceEmigh关于将'f'分解为2个单独的函数并独立测试它们,我认为尽可能将事情分开是很好的做法。但迟早你必须将所有东西绑定在一起,而且你仍然需要测试你是否正确地将函数的参数传递给函数。 –