Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pytest logger stdout sink #1193

Open
ixenion opened this issue Aug 31, 2024 · 1 comment
Open

pytest logger stdout sink #1193

ixenion opened this issue Aug 31, 2024 · 1 comment
Labels
question Further information is requested

Comments

@ixenion
Copy link

ixenion commented Aug 31, 2024

Hey, what's up!

How did you manage to conduct sink=sys.stdout test like in your tests/test_add_sinks.py:

@repetitions
def test_stderr_sink(rep, capsys):
    log(sys.stderr, rep)
    out, err = capsys.readouterr()
    assert out == ""
    assert err == expected * rep

?

Because when I create my own test function:

from loguru import logger
def test_stdout_sink(capsys) -> None:
    # By default logger already writes to stdout
    # So Im not setting anything here.
    message = f"Hello"
    logger.info(message)
    out, err = capsys.readouterr()
    assert message in out

I got accert error:

accert "Hello" == ""

For some reason I cant catch logger stdout with capsys. "out" is just empty string.

What should I set to make it work?

Also there is pytest-loguru project, and what he does is add caplog.handler like so:

magic_handler_id = \
        logger.add(sink=caplog.handler, level=0)
message = f"Test info message"
logger.info(message)
assert message in caplog.text

And it passes :) . The fun is that he don't test sys.stdout with this approach.

@ixenion ixenion changed the title pytest logger pytest logger stdout sink Aug 31, 2024
@Delgan Delgan added the question Further information is requested label Sep 22, 2024
@Delgan
Copy link
Owner

Delgan commented Sep 22, 2024

Hi @ixenion.

The problem with your test is that, at the time the test function is called, the logger is already configured with the sys.stdout default sink. Therefore, although capsys will replace sys.stdout for testing purpose, the logger won't perceive this change. The logger will write to an outdated reference of sys.stdout, and capsys won't capture the logs.

As a workaround, you actually need to call logger.add(sys.stdout) within your test (despite your comment in code stating the opposite, sorry :) ):

from loguru import logger

def test_stdout_sink(capsys) -> None:
    logger.add(sys.stdout)
    message = f"Hello"
    logger.info(message)
    out, err = capsys.readouterr()
    assert message in out

This is actually done in the log() function of my own tests:

def log(sink, rep=1):
logger.debug("This shouldn't be printed.")
i = logger.add(sink, format="{message}")
for _ in range(rep):
logger.debug(message)
logger.remove(i)
logger.debug("This shouldn't be printed neither.")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants