未定义Unittest子测试中的局部变量。

最后发布: 2020-07-09


问题

我有一个 unittest 的测试任务。我得到了NameError error: name 'x' is not defined 在每个子测试中.在看了课程材料和文档后,我无法找出错误的原因。我如何解决这个问题?

    import unittest


    def factorize(x):
        """
        Factorize positive integer and return its factors.
        :type x: int,>=0
        :rtype: tuple[N],N>0
        """
        pass


    class TestFactorize(unittest.TestCase):
        def test_wrong_types_raise_exception(self):
            cases = ['string', 1]
            for case in cases:
                with self.subTest(x=case):
                    print(x)
                    self.assertRaises(TypeError, factorize, x)

        def test_negative(self):
            cases = [-1, -10, -100]
            for case in cases:
                with self.subTest(x=case):
                    self.assertRaises(ValueError, factorize, x)

        def test_zero_and_one_cases(self):
            cases = [0, 1]
            for case in cases:
                with self.subTest(x=case):
                    self.assertEqual(factorize(x), (x,))

        def test_simple_numbers(self):
            cases = [3, 13, 29]
            for case in cases:
                with self.subTest(x=case):
                    self.assertEqual(factorize(x), (x,))


    if __name__ == '__main__':
        unittest.main()
python python-unittest
回答

subtest 没有定义一个新的局部变量 x. x 只是测试失败时作为错误信息一部分的名称。例如,你需要继续使用 case 在你的测试代码中。

def test_wrong_types_raise_exception(self):
    cases = ['string', 1]
    for case in cases:
        with self.subTest(x=case):
            print(case)
            self.assertRaises(TypeError, factorize, case)

现在,当测试失败时,你会看到每个子测试都用字符串标记,如 x=...,其值为 case 导致失败。

======================================================================
FAIL: test_wrong_types_raise_exception (__main__.TestFactorize) (x='string')
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tmp.py", line 19, in test_wrong_types_raise_exception
    self.assertRaises(TypeError, factorize, case)
AssertionError: TypeError not raised by factorize

将调用改为 subTest(foo=case) 会导致标签变成 foo='string'.