在另一个Python包中运行pytest测试

时间:2014-01-09 20:59:59

标签: python pytest

现在,我有一个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的测试。这可能吗?

unittest

的示例

在切换到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>

1 个答案:

答案 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拼凑一些东西。但是。