How do I remove a handler from a loguru.logger when using pytest?
Question:
I wrote a Thing
class that does logging using loguru
. At the bottom of the class file I add a handler to the logger. This is what thing.py
looks like.
from loguru import logger
class Thing:
def __init__(self):
logger.info("Thing created")
def __enter__(self):
logger.info("Thing entered")
return self
def __exit__(self, exc_type, exc_value, traceback):
logger.info("Thing exited")
logger.add("thing.log")
if __name__ == "__main__":
with Thing() as thing:
logger.info("In with block")
This works fine and it logs to thing.log as expected. What I would like to achieve is that it does not add the handler to thing.log when running tests.
This is my test file:
import pytest
from loguru import logger
from thing import Thing
@pytest.fixture
def thing(mocker):
mocker.patch("thing.logger", logger)
with Thing() as thing:
yield thing
def test_thing(thing, mocker):
mocker.patch("thing.logger", logger)
logger.info("In test")
assert isinstance(thing, Thing)
Now this test passes, but the logs are still written to thing.log (instead to only stdout, which is the default in for a loguru.logger).
How do I make sure that it only logs to the basic loguru.logger
when running pytest?
What I tried:
- Using monkeypatch instead of using mocker:
monkeypatch.setattr("thing.logger", logger)
- Patching in only one place (either in the fixture or in the test function)
- Patching without replacement:
mocker.patch("thing.logger")
(so without a replacement logger)
Answers:
Remove logger.add("thing.log")
from thing.py
!
You can either specify (as said in the docs) that you want to log to stdout
: logger.add(sys.stdout)
or just leave it out because the default for loguru.logger
is in fact stdout
!
The example provided in their docs:
logger.add(sys.stdout, format="{time} - {level} - {message}", filter="sub.module")
EDIT:
if __name__ == "__main__":
logger.add("thing.log")
if __name__ == "__main__":
with Thing() as thing:
#...
Now the logger will log to thing.log
when the module is executed directly, but it will NOT add the file handler when the module is imported by another module (e.g. a test file).
Or you can use logger.remove(0)
to stop logging when calling thing(mocker)
!
I wrote a Thing
class that does logging using loguru
. At the bottom of the class file I add a handler to the logger. This is what thing.py
looks like.
from loguru import logger
class Thing:
def __init__(self):
logger.info("Thing created")
def __enter__(self):
logger.info("Thing entered")
return self
def __exit__(self, exc_type, exc_value, traceback):
logger.info("Thing exited")
logger.add("thing.log")
if __name__ == "__main__":
with Thing() as thing:
logger.info("In with block")
This works fine and it logs to thing.log as expected. What I would like to achieve is that it does not add the handler to thing.log when running tests.
This is my test file:
import pytest
from loguru import logger
from thing import Thing
@pytest.fixture
def thing(mocker):
mocker.patch("thing.logger", logger)
with Thing() as thing:
yield thing
def test_thing(thing, mocker):
mocker.patch("thing.logger", logger)
logger.info("In test")
assert isinstance(thing, Thing)
Now this test passes, but the logs are still written to thing.log (instead to only stdout, which is the default in for a loguru.logger).
How do I make sure that it only logs to the basic loguru.logger
when running pytest?
What I tried:
- Using monkeypatch instead of using mocker:
monkeypatch.setattr("thing.logger", logger)
- Patching in only one place (either in the fixture or in the test function)
- Patching without replacement:
mocker.patch("thing.logger")
(so without a replacement logger)
Remove logger.add("thing.log")
from thing.py
!
You can either specify (as said in the docs) that you want to log to stdout
: logger.add(sys.stdout)
or just leave it out because the default for loguru.logger
is in fact stdout
!
The example provided in their docs:
logger.add(sys.stdout, format="{time} - {level} - {message}", filter="sub.module")
EDIT:
if __name__ == "__main__":
logger.add("thing.log")
if __name__ == "__main__":
with Thing() as thing:
#...
Now the logger will log to thing.log
when the module is executed directly, but it will NOT add the file handler when the module is imported by another module (e.g. a test file).
Or you can use logger.remove(0)
to stop logging when calling thing(mocker)
!