如何在pytest中全局修补? [英] How to patch globally in pytest?

查看:54
本文介绍了如何在pytest中全局修补?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码经常使用 pytest.示例代码结构如下所示.整个代码库是python-2.7

I use pytest quite a bit for my code. Sample code structure looks like this. The entire codebase is python-2.7

core/__init__.py
core/utils.py

#feature

core/feature/__init__.py
core/feature/service.py

#tests
core/feature/tests/__init__.py
core/feature/tests/test1.py
core/feature/tests/test2.py
core/feature/tests/test3.py
core/feature/tests/test4.py
core/feature/tests/test10.py

service.py 看起来像这样:

from modules import stuff
from core.utils import Utility


class FeatureManager:
    # lots of other methods
    def execute(self, *args, **kwargs):
        self._execute_step1(*args, **kwargs)
        # some more code
        self._execute_step2(*args, **kwargs)
        utility = Utility()
        utility.doThings(args[0], kwargs['variable'])

feature/tests/* 中的所有测试最终都使用了 core.feature.service.FeatureManager.execute 函数.但是 utility.doThings() 在我运行测试时不需要运行.我需要它在生产应用程序运行时发生,但我不希望它在测试运行时发生.

All the tests in feature/tests/* end up using core.feature.service.FeatureManager.execute function. However utility.doThings() is not necessary for me to be run while I am running tests. I need it to happen while the production application runs but I do not want it to happen while the tests are being run.

我可以在我的 core/feature/tests/test1.py

from mock import patch

class Test1:
   def test_1():
       with patch('core.feature.service.Utility') as MockedUtils:
           exectute_test_case_1()

这行得通.但是我刚刚在代码库中添加了 Utility 并且我有 300 多个测试用例.我不想进入每个测试用例并编写这个 with 语句.

This would work. However I added Utility just now to the code base and I have more than 300 test cases. I would not want to go into each test case and write this with statement.

我可以编写一个 conftest.py 来设置操作系统级别的环境变量,core.feature.service.FeatureManager.execute 可以根据该变量决定不执行utility.doThings 但我不知道这是否是这个问题的干净解决方案.

I could write a conftest.py which sets a os level environment variable based on which the core.feature.service.FeatureManager.execute could decide to not execute the utility.doThings but I do not know if that is a clean solution to this issue.

如果有人可以帮助我为整个会话提供全局补丁,我将不胜感激.我想在整个会话中全局执行上面的 with 块.任何关于这方面的文章也会很棒.

I would appreciate if someone could help me with global patches to the entire session. I would like to do what I did with the with block above globally for the entire session. Any articles in this matter would be great too.

TLDR:如何在运行 pytests 时创建会话范围的补丁?

TLDR: How do I create session wide patches while running pytests?

推荐答案

我添加了一个名为 core/feature/conftest.py 的文件,看起来像这样

I added a file called core/feature/conftest.py that looks like this

import logging
import pytest


@pytest.fixture(scope="session", autouse=True)
def default_session_fixture(request):
    """
    :type request: _pytest.python.SubRequest
    :return:
    """
    log.info("Patching core.feature.service")
    patched = mock.patch('core.feature.service.Utility')
    patched.__enter__()

    def unpatch():
        patched.__exit__()
        log.info("Patching complete. Unpatching")

    request.addfinalizer(unpatch)

这并不复杂.就像在做

with mock.patch('core.feature.service.Utility') as patched:
    do_things()

但仅限于会话范围的方式.

but only in a session-wide manner.

这篇关于如何在pytest中全局修补?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆