有全局夹具时如何将python unittests转换为py.test?

sor*_*rin 4 python fixtures pytest python-unittest xdist

我确实有一组使用python的unittest模块编写的单元测试。他们正在使用setUpModule()函数来加载具有运行测试(包括某些http会话)所需的共享“材料”的全局变量。

当使用进行我的测试时unittest,它们py.test无法正常运行。

我对其进行了一些修补,以使其使用旧的pytest夹具函数(恰好与unittest的函数名称不同)运行。有效,但仅当未在多个线程上执行时,这是我要使用的功能。

在我的情况下,文档示例没有用,因为我确实有20个类(unittest.TestCase),每个类内部有10个测试。显然,我不想为每个测试添加新参数。

到目前为止,我使用类setUp()方法将共享字典加载到self内,并在每个测试中使用它的形式。

#!/usr/bin/env python
# conftest.py 
@pytest.fixture(scope="session")
def manager():
    return { "a": "b"}
Run Code Online (Sandbox Code Playgroud)

现在测试:

#!/usr/bin/env python
# tests.py 

class VersionTests(unittest.TestCase):

    def setUp(self):
        self.manager = manager

    def test_create_version(self):
        # do something with self.manager
        pass
Run Code Online (Sandbox Code Playgroud)

请记住,我需要一个可以与多个线程一起使用的解决方案,一次调用固定装置。

fam*_*kin 5

pytest可以unittest确保运行测试,如对unittest.TestCase /夹具集成的支持中所述。棘手的部分是不建议直接使用pytestfuncargs装置

虽然pytest支持通过非单位测试方法的测试函数参数接收固定装置,但unittest.TestCase方法无法直接接收固定装置函数参数,因为实现可能会影响运行常规unittest.TestCase测试套件的能力。

假设我们有一个使用标准unittest初始化工具的测试模块,如下所示:

# test_unittest_tests.py (for the sake of clarity!)
import unittest

manager = None

def setUpModule():
    global manager
    manager = {1: 2}

class UnittestTests(unittest.TestCase):
    def setUp(self):
        self.manager = manager

    def test_1_in_manager(self):
        assert 1 in self.manager

    def test_a_in_manager(self):
        assert 'a' in self.manager
Run Code Online (Sandbox Code Playgroud)

与一起运行时会产生以下输出unittest

$ python -m unittest -v test_unittest_tests
...
test_1_in_manager (test_unittest_tests.UnittestTests) ... ok
test_a_in_manager (test_unittest_tests.UnittestTests) ... FAIL
...
Run Code Online (Sandbox Code Playgroud)

test_a_in_manager未按预期的,没有'a'在关键的manager目录。

我们设置了conftest.py来pytest为这些测试提供范围内的夹具。像这样,例如,在不破坏标准unittest行为的情况下,完全不需要使用pytestautouse进行测试:

# conftest.py
import pytest

@pytest.fixture(scope='session', autouse=True)
def manager_session(request):
    # create a session-scoped manager
    request.session.manager = {'a': 'b'}

@pytest.fixture(scope='module', autouse=True)
def manager_module(request):
    # set the sessions-scoped manager to the tests module at hand
    request.module.manager = request.session.manager
Run Code Online (Sandbox Code Playgroud)

使用pytest(使用pytest-xdist)运行测试以进行并行化,将产生以下输出:

$ py.test -v -n2
...
[gw1] PASSED test_unittest_tests.py:17: UnittestTests.test_a_in_manager 
[gw0] FAILED test_unittest_tests.py:14: UnittestTests.test_1_in_manager 
...
Run Code Online (Sandbox Code Playgroud)

现在test_1_in_manager失败了,提供的管理器字典中没有1密钥pytest