首页 文章

如何在拥有全局灯具时将python单元测试转换为py.test?

提问于
浏览
2

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

使用 unittest 运行我的测试时,它们运行正常 py.test 它们失败了 .

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

在我的案例中,文档示例是无用的,因为我确实有20个类(unittest.TestCase),每个类中有10个测试 . 显然,我不想为每个测试添加新参数 .

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

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

  • 4

    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 按预期失败, 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 提供的经理字典中没有 1 键 .

相关问题