我有一个JSON解析器库(ijson)和一个使用unittest的测试套件。该库实际上有几个解析实现 - “后端” - 以具有相同API的模块的形式。我想为每个可用的后端自动运行测试套件几次。我的目标是:
那么为此组织测试套件的最佳方法是什么?写一个自定义测试运行器?让TestCases自己加载后端吗?势必为每个后端生成单独的TestCase类?
顺便说一下,我并没有特别嫁给unittest图书馆,如果能解决问题的话我会尝试另外一个。但是unittest是可取的,因为我已经有了测试代码。
答案 0 :(得分:1)
一种常见的方法是使用创建后端实例的抽象方法将所有测试组合在一个类中(如果需要在测试中创建多个实例),或者期望setUp
创建一个后端的实例。
然后,您可以根据需要创建创建不同后端的子类。
如果您使用的是自动检测TestCase
子类的测试加载器,您可能需要进行一次更改:不要将公共基类作为TestCase
的子类:而是对待它作为mixin,并使TestCase
和mixin的后端类子类化。
例如:
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
,用于测试两个后端的相同功能。
答案 1 :(得分: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