Python Unittest2 - 避免在discover()中包含TestCase

3 投票
1 回答
684 浏览
提问于 2025-04-16 19:13

我在使用 unittest2Python2.5 来发现测试,方法是用 unittest.TestLoader.discover,像这样:

suite = unittest2.loader.TestLoader().discover(test_path)
unittest2.TextTestRunner(verbosity=2,
        resultclass=ColorTestResult).run(suite)

在我项目的根目录下有一个 test_path

我有一个基础类,这个类被很多其他类扩展和重载,但我想测试这些派生类是否没有出现问题。我们把这个基础类叫做 A,它的派生类叫做 A1A2,等等。

我想创建一个 unittest2.TestCase 的基础类,可以为每个 A 的派生类进行重载。换句话说,我想要一个类似于下面这样的层次结构:

class A:
    pass

class A1(A):
    pass

class UT(unittest2.TestCase):
    target = A

class UT2(UT):
    target = A1

现在关键是,我把 A 设成一个抽象类,而 UT 在几乎所有的测试用例中都会失败,而这些测试用例在 UT2 等等中应该是可以通过的。

对我来说,最简单的解决办法似乎是让 unittest2 的 discover 以某种方式“跳过” UT。我认为这可以通过把它放在一个不符合 'test*.py' 这个模式的文件中来实现,但看起来并不是这样。

有没有什么合适的解决方案来应对上述情况呢?

我会很感激任何想法和建议。

1 个回答

2

我猜问题出在UT2是从UT继承的,所以定义UT2的模块导入了UT,这样UT就可以在模块的命名空间中使用。因此,即使发现功能没有查看UT定义的模块,它仍然可以在UT2模块中找到TestCase。

这是一个常见的问题,尤其是当基础的TestCases本身也定义了测试时。

有几种解决方案。一个方法是通过一个函数来暴露UT,这样包含UT2的模块就可以导入这个函数,而不是直接导入UT:

class UT2(get_base_class()):
    target = A1

可以通过super()来访问UT上的属性。

另一个可能更好的解决方案是让UT变得更抽象。你可以省略UT上的目标(因为它似乎没有什么用?),并让setUp在没有目标(或者目标是A)的情况下调用skipTest。

第三种解决方案是让UT不继承自TestCase,而是将其作为一个混入类使用:

class UT2(TestCase, UT):
     target = A1

撰写回答