在单元测试

时间:2016-12-14 02:58:21

标签: python unit-testing testing python-unittest

我正在尝试使用load_tests protocol来参数化一些测试用例。这是我的MCVE:

# mytests.py
import unittest

class MyTests(unittest.TestCase):
  def __init__(self, x, y):
    super(MyTests, self).__init__("testMyMethod")
    self.x = x
    self. y = y

  def testMyMethod(self):
    self.assertEqual(self.y, my_method(self.x))

def load_tests(loader, tests, pattern):
  print("load_tests()")
  foobar = zip(range(5), range(5))
  test_suite = unittest.TestSuite()
  for x, y in foobar:
    test_suite.addTest(MyTests(x, y))
  return test_suite

def my_method(x):
  return x

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

当我运行时,我得到以下输出:

myrdraal% python mytests.py 
Traceback (most recent call last):
  File "mytests.py", line 24, in <module>
    unittest.main()
  File "/usr/lib/python3.5/unittest/main.py", line 93, in __init__
    self.parseArgs(argv)
  File "/usr/lib/python3.5/unittest/main.py", line 140, in parseArgs
    self.createTests()
  File "/usr/lib/python3.5/unittest/main.py", line 144, in createTests
    self.test = self.testLoader.loadTestsFromModule(self.module)
  File "/usr/lib/python3.5/unittest/loader.py", line 123, in loadTestsFromModule
    tests.append(self.loadTestsFromTestCase(obj))
  File "/usr/lib/python3.5/unittest/loader.py", line 92, in loadTestsFromTestCase
    loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
  File "/usr/lib/python3.5/unittest/suite.py", line 24, in __init__
    self.addTests(tests)
  File "/usr/lib/python3.5/unittest/suite.py", line 57, in addTests
    for test in tests:
TypeError: __init__() missing 1 required positional argument: 'y'

似乎我的load_tests()甚至没有被调用。我做错了什么?

类似的MCVE运行得很好:

# parameterized.py
import unittest

class ParameterizedTest(unittest.TestCase):
  def __init__(self, value):
    super(ParameterizedTest, self).__init__("test")
    self.value = value

  def test(self):
    self.assertEqual(self.value, self.value)

def load_tests(loader, tests, pattern):
  test_suite = unittest.TestSuite()
  for i in range(5):
    test_suite.addTest(ParameterizedTest(i))
  return test_suite

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

输出2:

myrdraal% python parameterized.py
.....
----------------------------------------------------------------------
Ran 5 tests in 0.001s

OK

显然我错过了一些东西,因为它们看起来和我类似。

1 个答案:

答案 0 :(得分:1)

问题似乎是unittest框架在__init__()的每个子类上为每个以&#34; test&#34;开头的方法调用unittest.TestCase。它传递一个参数,该参数是包含测试方法名称的字符串。这一切都在调用load_tests()之前发生。一种解决方案是修改__init__()以允许此机制运行:

class MyTests(unittest.TestCase):
  def __init__(self, testName, x=None, y=None):
    super(MyTests, self).__init__(testName)
    self.x = x
    self. y = y

  def testMyMethod(self):
    self.assertEqual(self.y, my_method(self.x))

def load_tests(loader, tests, pattern):
  print("load_tests()")
  foobar = zip(range(5), range(5))
  test_suite = unittest.TestSuite()
  for x, y in foobar:
    test_suite.addTest(MyTests('testMyMethod', x, y))
  return test_suite