单元测试中的代码重用性?

6

我听到很多人说测试应该简单、易于维护和直观,但在单元测试中如何实现代码的可重用性呢?

让我们举个例子:

def test_some_1():
    ...some code

def test_some_2():
    ...code repeated from test_some_1

在两个测试中,将重复的代码封装在一个包含必要断言的函数中是否最好?我曾与一些程序员争论过这个问题,他们不同意。他们认为测试应该是简单的,这里不需要代码可重用性。原因是在Django控制台中,由于断言在函数中,所以很难确定断言实际上失败了,虽然我不同意,因为使用nose会给出测试名称和回溯信息,但那些人再次不同意,称测试可以单独调用而不使用nose(因此无法看到所有这些细节)。你们认为呢?
  • 在单元测试中使用代码可重用性是否好?
  • 如果可重用性可/必须使用,如何解决关于定位断言的另一个问题?

你知道setUptearDown吗?https://docs.python.org/2/library/unittest.html#unittest.TestCase.setUp - Mihai Zamfir
我知道,但我不认为它们在这里相关。我在谈论代码可重用性。请查看@otus的答案。 - andreihondrari
2个回答

6
最重要的代码质量因素,如清晰度和可读性,对测试代码同样重要。如果代码重复能使其更易于阅读,无论你写的是测试代码还是其他代码,都应该这样做。例如,在我编写的一个包中,我有一个函数:
def _test_vector(self, a, b, c):
    # test the function with parameter values a, b, c
    # several asserts here to verify output of function tested

这使我能够编写所有测试向量,例如:

def test_vector1(self):
    self._test_vector(a=42, b=5, c="blah)

在我看来,这样做可以提高清晰度,因为每个单独的测试只包含特定于该测试的信息。

定位断言应该总是很容易的。即使是 unittest 也会给你一个回溯,如果你的测试设置没有指向特定的断言,你将很难调试任何测试失败,并且应该切换到一些明智的东西。


我在这里找到了一个略微不同的观点,我同意,并且你也可能想考虑一下:https://osherove.com/blog/2007/9/22/code-reuse-in-unit-tests-is-more-important-than-you-think.html - ana

0

正如你的同行所说,你应该写简单的测试。这样做有几个原因,其中最重要的是你想避免在测试中使用复杂的逻辑。如果你把测试写得太“聪明”,它们往往会包含与你试图测试的代码相同或类似的逻辑。这意味着你冒着在两个地方犯同样错误的风险,并且会错过你想要找到的错误。

另一个原因是你希望你的测试能够作为你试图测试的代码的文档。如果测试覆盖了许多函数和逻辑,执行路径比较复杂,那么理解起来就不那么容易了。在最好的情况下,只需要一眼扫过测试就能看到生产代码的预期工作方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接