【问题标题】:How can I convert Python unittests to py.test when having global fixtures?拥有全局固定装置时,如何将 Python 单元测试转换为 py.test?
【发布时间】:2014-07-19 09:44:20
【问题描述】:

我确实有一组使用 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"}

现在是测试:

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

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

【问题讨论】:

    标签: python fixtures pytest python-unittest xdist


    【解决方案1】:

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

    虽然 pytest 支持通过非 unittest 测试方法的测试函数参数接收夹具,但 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
    

    使用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 按预期失败。 manager 目录中没有任何 'a' 键。

    我们设置了一个 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 失败了; pytest-provided manager 字典中没有任何 1 键。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-18
      • 2011-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-11
      相关资源
      最近更新 更多