3

我有一个 JSON 解析器库(ijson)和一个使用 unittest 的测试套件。该库实际上有几个解析实现——“后端”——以具有相同 API 的模块的形式。我想为每个可用的后端自动运行几次测试套件。我的目标是:

  • 我想将所有测试保存在一个地方,因为它们与后端无关。
  • 我希望当前使用的后端的名称在测试失败时以某种方式可见。
  • 我希望能够像 unittest 通常允许的那样运行单个 TestCase 或单个测试。

那么为此组织测试套件的最佳方法是什么?编写自定义测试运行器?让 TestCases 自己加载后端?必须为每个后端生成单独的 TestCase 类?

顺便说一句,我并没有特别与 unittest 库结婚,如果它解决了问题,我愿意尝试另一个。但是 unittest 更可取,因为我已经有了测试代码。

4

2 回答 2

1

一种常见的方法是使用一个抽象方法将所有测试组合在一个类中,该方法创建一个后端实例(如果您需要在测试中创建多个实例),或者期望setUp创建一个后端实例。

然后,您可以根据需要创建创建不同后端的子类。

如果您正在使用自动检测TestCase子类的测试加载器,您可能需要进行一项更改:不要将公共基类TestCase设为 : 的子类,而是将其视为 mixin,并让后端类同时从TestCase和混音。

例如:

class BackendTests:
    def make_backend(self):
        raise NotImplementedError

    def test_one(self):
        backend = self.make_backend()
        # perform a test on the backend

class FooBackendTests(unittest.TestCase, BackendTests):
    def make_backend(self):
        # Create an instance of the "foo" backend:
        return foo_backend

class BarBackendTests(unittest.TestCase, BackendTests):
    def make_backend(self):
        # Create an instance of the "bar" backend:
        return bar_backend

从上面构建测试套件时,您将拥有独立的测试用例FooBackendTests.test_one,并BarBackendTests.test_one在两个后端测试相同的功能。

于 2012-10-15T02:51:04.450 回答
1

我将 James Henstridge 的想法与一个包含所有测试的 mixin 类一起使用,但实际的测试用例随后会强制生成,因为后端可能在导入时失败,在这种情况下我们不想测试它们:

class BackendTests(object):
    def test_something(self):
        # using self.backend 

# Generating real TestCase classes for each importable backend
for name in ['backend1', 'backend2', 'backend3']:
    try:
        classname = '%sTest' % name.capitalize()
        locals()[classname] = type(
            classname,
            (unittest.TestCase, BackendTests),
            {'backend': import_module('backends.%s' % name)},
        )
    except ImportError:
        pass
于 2012-10-16T07:44:41.083 回答