有全局装置时如何将python单元测试转换为pytest?

时间:2014-07-19 09:44:21

标签: python fixtures pytest python-unittest xdist

我确实有一组使用python的unittest模块编写的单元测试。他们使用setUpModule()函数加载一个全局变量,其中包含共享的#34; stuff"这是运行测试所必需的(包括一些http sesions)。

使用unittest运行我的测试时,它们在py.test运行良好时会失败。

我修补了一下它使用旧的pytest fixture函数运行(它的名称与unittest函数不同)。工作但只有在多线程上没有执行时,这才是我想要使用的功能。

文档示例对我来说没用,因为我确实有20个类(unittest.TestCase),每个类中有10个测试。显然,我不想为每个测试添加新参数。

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

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

现在测试:

#!/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

请记住,我需要一个可以使用多个线程的解决方案,一次调用夹具。

1 个答案:

答案 0 :(得分:5)

pytest可以肯定运行unittest测试,如Support for unittest.TestCase / Integration of fixtures中所述。棘手的部分是不鼓励直接使用pytest funcargs fixtures

  

虽然pytest支持通过非单元测试方法的测试函数参数接收fixture,但是unittest.TestCase方法不能直接接收fixture函数参数作为实现可能会导致运行通用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

使用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
...

test_a_in_manager按预期失败,'a'目录中没有manager个密钥。

我们设置了一个conftest.py来为这些测试提供范围pytest的固定装置。例如,在不违反标准unittest行为的情况下,无需使用pytest autouse完全触及测试:

# 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

使用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 
...

现在,test_1_in_manager失败了,1中没有pytest个密钥 - 提供了管理员字典。