简体   繁体   中英

Python deactivate loguru.logger.catch() function when run in pytest

I am using loguru.logger.catch() function to log some outputs. Also, I want to deactivate this function when I test my class with pytest. I've tried to use monkey patch but didn't work. How can I handle this situation?

Example Code:

class DividerClass:

    @logger.catch
    def __init__(self, num1, num2):
        self.num1 = num1
        self.num2 = num2

        if self.num2 == 0:
            raise ZeroDivisionError
        else:
            self.result = self.num1 / self.num2
            logger.info(f"DividerClass {self.num1} / {self.num2} = {self.result}")


def test_divider_class_with_zero(monkeypatch):
    monkeypatch.setattr(loguru.logger, "catch", lambda x: x)
    
    with pytest.raises(ZeroDivisionError):
        DividerClass(0, 0)

You could try using the loguru disable method logger.disable(None) .

Depending on the structure of you code, you can pass along the module's name instead of None to disable logging just for that module.

With logger.enable(...) you can afterwards re-enable logging for the other tests.

See the loguru documentation for the disable method for more details.

The issue comes down to when the decorator is applied. By the time test collection has finished, the decorator is already applied to the function. Due to this we have two options:

  1. Import the desired object after patching
  2. Reload the module after patching

In the code below I show the former approach. This code also assumes your test files live in a separate file from your actual code.

# src/manager.py

from loguru import logger

class DividerClass:

    @logger.catch
    def __init__(self, num1, num2):
        self.num1 = num1
        self.num2 = num2

        if self.num2 == 0:
            raise ZeroDivisionError
        else:
            self.result = self.num1 / self.num2
            logger.info(f"DividerClass {self.num1} / {self.num2} = {self.result}")


# tests/test_manager.py

import pytest
import loguru

def test_divider_class_with_zero(monkeypatch):
    monkeypatch.setattr(loguru.logger, "catch", lambda x: x)
    # notice the import happens after the patch
    from src.manager import DividerClass
    
    with pytest.raises(ZeroDivisionError):
        DividerClass(0, 0)

=============================================== test session starts ================================================
platform darwin -- Python 3.8.9, pytest-7.0.1, pluggy-1.0.0
rootdir: ***
plugins: asyncio-0.18.3, xdist-2.5.0, forked-1.4.0, hypothesis-6.48.1, mock-3.7.0
asyncio: mode=strict
collected 1 item                                                                                                   

tests/test_manager.py .                                                                                      [100%]

================================================ 1 passed in 0.02s =================================================

Please read this excellent answer here to learn more.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM