阅读(4860) (0)

pytest fixture-重写各种级别的fixture

2022-03-18 13:58:09 更新

在相对较大的测试套件中,您很可能需要用本地定义的​​fixture​​覆盖全局或根​​fixture​​,以保持测试代码的可读性和可维护性。

覆盖文件夹(conftest)级别上的fixture

假设测试文件结构是:

tests/
    __init__.py

    conftest.py
        # content of tests/conftest.py
        import pytest

        @pytest.fixture
        def username():
            return 'username'

    test_something.py
        # content of tests/test_something.py
        def test_username(username):
            assert username == 'username'

    subfolder/
        __init__.py

        conftest.py
            # content of tests/subfolder/conftest.py
            import pytest

            @pytest.fixture
            def username(username):
                return 'overridden-' + username

        test_something.py
            # content of tests/subfolder/test_something.py
            def test_username(username):
                assert username == 'overridden-username'

正如您所看到的,具有相同名称的​​fixture​​可以为特定的测试文件夹级别重写。请注意,可以从上面示例中使用的覆盖​​fixture​​轻松访问基​本​fixture​​或超级​​fixture​​

覆盖测试模块级别上的fixture

假设测试文件结构是:

tests/
    __init__.py

    conftest.py
        # content of tests/conftest.py
        import pytest

        @pytest.fixture
        def username():
            return 'username'

    test_something.py
        # content of tests/test_something.py
        import pytest

        @pytest.fixture
        def username(username):
            return 'overridden-' + username

        def test_username(username):
            assert username == 'overridden-username'

    test_something_else.py
        # content of tests/test_something_else.py
        import pytest

        @pytest.fixture
        def username(username):
            return 'overridden-else-' + username

        def test_username(username):
            assert username == 'overridden-else-username'

在上面的示例中,可以为某些测试模块重写具有相同名称的​fixture​。

覆盖具有直接测试参数化的fixture

假设测试文件结构是:

tests/
    __init__.py

    conftest.py
        # content of tests/conftest.py
        import pytest

        @pytest.fixture
        def username():
            return 'username'

        @pytest.fixture
        def other_username(username):
            return 'other-' + username

    test_something.py
        # content of tests/test_something.py
        import pytest

        @pytest.mark.parametrize('username', ['directly-overridden-username'])
        def test_username(username):
            assert username == 'directly-overridden-username'

        @pytest.mark.parametrize('username', ['directly-overridden-username-other'])
        def test_username_other(other_username):
            assert other_username == 'other-directly-overridden-username-other'

在上面的示例中,​​fixture​​值被测试参数值覆盖。请注意,即使测试没有直接使用​​fixture​​的值(在函数原型中没有提到它),也可以通过这种方式重写它。

用非参数化fixture覆盖参数化fixture

假设测试文件结构是:

tests/
    __init__.py

    conftest.py
        # content of tests/conftest.py
        import pytest

        @pytest.fixture(params=['one', 'two', 'three'])
        def parametrized_username(request):
            return request.param

        @pytest.fixture
        def non_parametrized_username(request):
            return 'username'

    test_something.py
        # content of tests/test_something.py
        import pytest

        @pytest.fixture
        def parametrized_username():
            return 'overridden-username'

        @pytest.fixture(params=['one', 'two', 'three'])
        def non_parametrized_username(request):
            return request.param

        def test_username(parametrized_username):
            assert parametrized_username == 'overridden-username'

        def test_parametrized_username(non_parametrized_username):
            assert non_parametrized_username in ['one', 'two', 'three']

    test_something_else.py
        # content of tests/test_something_else.py
        def test_username(parametrized_username):
            assert parametrized_username in ['one', 'two', 'three']

        def test_username(non_parametrized_username):
            assert non_parametrized_username == 'username'

在上面的例子中,参数化的​​fixture​​被非参数化版本覆盖,非参数化的​​fixture​​被某个测试模块的参数化版本覆盖。这同样适用于测试文件夹级别。