我已经阅读了有关在Python单元测试的assert方法中使用setUp的一些相互矛盾的建议。如果测试所依赖的前提条件失败,我看不到测试失败的危害。

例如:

import unittest

class MyProcessor():
    """
    This is the class under test
    """

    def __init__(self):
        pass

    def ProcessData(self, content):
        return ['some','processed','data','from','content'] # Imagine this could actually pass

class Test_test2(unittest.TestCase):

    def LoadContentFromTestFile(self):
        return None # Imagine this is actually doing something that could pass.

    def setUp(self):
        self.content = self.LoadContentFromTestFile()
        self.assertIsNotNone(self.content, "Failed to load test data")
        self.processor = MyProcessor()

    def test_ProcessData(self):
        results = self.processor.ProcessData(self.content)
        self.assertGreater(results, 0, "No results returned")

if __name__ == '__main__':
    unittest.main()

这对我来说似乎是一件合理的事情,即确保测试能够运行。当由于设置条件而失败时,我们得到:
F
======================================================================
FAIL: test_ProcessData (__main__.Test_test2)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Projects\Experiments\test2.py", line 21, in setUp
    self.assertIsNotNone(self.content, "Failed to load test data")
AssertionError: unexpectedly None : Failed to load test data

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (failures=1)

最佳答案

setUp的目的是减少在安排阶段在测试类中的测试之间创建的Boilerplate code

在“安排”阶段,您:设置运行测试的代码所需的一切。这包括测试运行所需的依赖项,模拟和数据的任何初始化。

基于以上各段,您不应在setUp方法中声明任何内容。

因此,如前所述; 如果无法创建测试先决条件,则测试将被破坏。 为了避免出现这种情况,Roy Osherove写了一本很棒的书:The Art Of Unit Testing(为了充分披露Lior Friedman(他是Roy的老板)是我的 friend ,我与他们紧密合作了2年以上,所以我有点有偏见...)

基本上,在Arrange阶段与外部资源(或可能导致异常的事物)进行交互的原因很少,大多数(如果不是全部)都与集成测试相关。

回到你的例子;有一种结构化测试的模式
您需要加载外部资源(全部/大部分)。只是一个旁注;在决定应用此模式之前,请确保如果其他测试类需要使用此资源,则不要在UT的类中将此内容作为静态资源使用,请将此资源提取到模块中。

以下模式减少了失败的可能性,因为对外部资源的调用减少了:

class TestClass(unittest.TestCase):

    def setUpClass(self):
        # since external resources such as other servers can provide a bad content
        # you can verify that the content is valid
        # then prevent from the tests to run
        # however, in most cases you shouldn't.
        self.externalResourceContent = loadContentFromExternalResource()


    def setUp(self):
        self.content = self.copyContentForTest()

优点:
  • 减少失败的机会
  • 防止出现不一致行为(1.某项/一项已编辑了外部资源。2.您在某些测试中未能加载外部资源)
  • 执行速度更快

  • 缺点:
  • 代码更复杂
  • 10-05 21:23
    查看更多