将变量传递给我的unittest实例的最佳方式是什么?

3 投票
4 回答
5203 浏览
提问于 2025-04-17 12:57

我有一些测试类,它们是从unittest.TestCase这个类继承来的。我多次加载这些测试类,像这样:

tests = [TestClass1, TestClass2]
for test in tests:
    for var in array:
        # somehow indicate that this test should have the value of 'var'
        suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(test))

问题是,我想把'var'的值传递给每个测试,但我不能使用类变量,因为类变量是所有类的实例共享的。而且我也无法访问实际创建这些对象的代码。那么,有什么好的方法来实现这个呢?

4 个回答

0

更新:

因为你需要:

  1. 给 MyTestCase 提供一些变量值
  2. 用这个值运行 MyTestCase
  3. 更改这个值
  4. 如果 MyTestCase 还在运行 - 使用更新后的值。

考虑以下几点:

  1. 把值保存在一个文件里(.csv/.txt/.xml 等格式)
  2. setUp() 方法中从文件读取这些值
  3. 通过 TestCase.id() 方法从值中找到你需要的 MyTestCase 的值(下面的例子会展示如何做)。
  4. 在测试用例中使用这个值。

unittest 有一个很方便的 id() 方法,它会返回测试用例的名称,格式是 文件名.类名.方法名

所以你可以这样使用:

import unittest


my_variables_map = { 
    'test_01': 'foo',
    'test_02': 'bar',
}


class MyTest(unittest.TestCase):

    def setUp(self):
        test_method_name = self.id()  # filename.testclassname.methodname
        test_method_name = test_method_name.split('.')[-1]  # method name

        self.variable_value = my_variables_map.get(test_method_name)
        self.error_message = 'No values found for "%s" method.' % test_method_name

    def test_01(self):
        self.assertTrue(self.variable_value is not None, self.error_message)

    def test_02(self):
        self.assertTrue(self.variable_value is not None, self.error_message)

    def test_03(self):
        self.assertTrue(self.variable_value is not None, self.error_message)


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

这会给你:

$ python /tmp/ut.py 
..F
======================================================================
FAIL: test_03 (__main__.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/ut.py", line 25, in test_03
    self.assertTrue(self.variable_value is not None, self.error_message)
AssertionError: No values found for "test_03" method.

----------------------------------------------------------------------
Ran 3 tests in 0.000s

FAILED (failures=1)
$
0

我觉得你可能走错了方向。与其按照你现在的方式去做,不如试试这样,比如你在类里面有:

from my_tests.variables import my_array

class TestClass1(unittest.TestCase):

     def setUp():
         ....initializations...

     def tearDown():
         ....clean up after...

     def my_test_that_should_use_value_from_array(self):
         for value in my_array:
             test_stuff(value)
2

我觉得即使你不能直接访问那些实现测试案例的类,你也可以创建一个它们的子类,并重写其中的 setUp 方法。

撰写回答