现在,我有一个Python包(让我们称之为mypackage
),我用pytest运行了一堆测试。一个特定的功能可以有许多可能的实现,所以我使用了funcarg机制来使用参考实现来运行这些测试。
# In mypackage/tests/conftest.py
def pytest_funcarg__Feature(request):
return mypackage.ReferenceImplementation
# In mypackage/tests/test_stuff.py
def test_something(Feature):
assert Feature(1).works
现在,我正在创建一个单独的Python包,其中包含更高级的实现(fancypackage
)。 是否可以在mypackage
中运行包含Feature
funcarg的所有测试,只能使用不同的实现?
如果我在fancypackage
中添加新测试,我希望避免更改mypackage
,因此显式导入并不理想。我知道我可以使用pytest.main()
运行所有测试,但由于我有多个功能实现,因此我不想多次调用pytest.main()
。理想情况下,它看起来像这样:
# In fancypackage/tests/test_impl1.py
def pytest_funcarg__Feature(request):
return fancypackage.Implementation1
## XXX: Do pytest collection on mypackage.tests, but don't run them
# In fancypackage/tests/test_impl2.py
def pytest_funcarg__Feature(request):
return fancypackage.Implementation2
## XXX: Do pytest collection on mypackage.tests, but don't run them
然后,当我在fancypackage
中运行pytest时,它将收集每个mypackage.tests
次测试两次,每次为每个功能实现。我已尝试使用显式导入执行此操作,它似乎工作正常,但我不想显式导入所有内容。
另一个好处是仅收集那些包含Feature
funcarg的测试。这可能吗?
在切换到py.test之前,我使用标准库的unittest
进行了此操作。其功能如下:
def mypackage_test_suite(Feature):
loader = unittest.TestLoader()
suite = unittest.TestSuite()
mypackage_tests = loader.discover('mypackage.tests')
for test in all_testcases(mypackage_tests):
if hasattr(test, 'Feature'):
test.Feature = Feature
suite.addTest(test)
return suite
def all_testcases(test_suite_or_case):
try:
suite = iter(test_suite_or_case)
except TypeError:
yield test_suite_or_case
else:
for test in suite:
for subtest in all_testcases(test):
yield subtest
显然现在情况有所不同,因为我们正在处理测试函数和类而不仅仅是类,但似乎在py.test中应该有一些等价物来构建测试套件并允许你迭代它。 / p>
答案 0 :(得分:2)
您可以参数化Feature
灯具:
@pytest.fixture(params=['ref', 'fancy'])
def Feature(request):
if request.param == 'ref':
return mypackage.ReferenceImplementation
else:
return fancypackage.Implementation1
现在,如果你运行py.test,它将测试两者。
选择他们使用的灯具上的测试是不可能的AFAIK,您可以使用request.applymarker()
和-m
拼凑一些东西。但是。