There seems to be an issue with capturing stdout/stderr when using structlog with stdlib Logger in tests.
I've raised an issue with structlog but they are not convinced the problem originates there since the logs are simply passed to the stdlib Logger.
I've traced this down to the click's isolation context manager which seems to replace sys.stdout/sys.stderr with mocks during testing and my guess would be that this could have something to do with the problem but I'm hoping you may know better.
I've tried numerous things like explicitly setting a StreamHandler(sys.stderr) to the stdlib basicConfig, experimented with mix_stderr etc. nothing helped. Any ideas how to fix or work around this issue would be most welcome, thank you.
An example
# app.py
import structlog
import click
logger = structlog.get_logger()
structlog.configure(logger_factory=structlog.stdlib.LoggerFactory())
@click.command()
def hello() -> None:
logger.info("Hello!")
if __name__ == '__main__':
hello()
A test case:
# test_app.py
from click.testing import CliRunner
from app import hello
def test_log() -> None:
runner = CliRunner()
result = runner.invoke(hello)
print(result.stdout)
assert "Hello" in result.stdout
Expected
Hello! (to be printed)
assertion to pass
Actual
nothing printed (result.stdout is empty)
assertion failure:
> assert "Hello" in result.stdout
E AssertionError: assert 'Hello' in ''
E + where '' = <Result okay>.stdout
test_app.py:8: AssertionError```
Environment: macOS
- Python version: 3.12.7
- Click version: 8.1.7
There seems to be an issue with capturing stdout/stderr when using
structlogwith stdlibLoggerin tests.I've raised an issue with
structlogbut they are not convinced the problem originates there since the logs are simply passed to the stdlib Logger.I've traced this down to the click's
isolationcontext manager which seems to replacesys.stdout/sys.stderrwith mocks during testing and my guess would be that this could have something to do with the problem but I'm hoping you may know better.I've tried numerous things like explicitly setting a
StreamHandler(sys.stderr)to the stdlibbasicConfig, experimented withmix_stderretc. nothing helped. Any ideas how to fix or work around this issue would be most welcome, thank you.An example
A test case:
Expected
Hello! (to be printed)
assertion to pass
Actual
nothing printed (result.stdout is empty)
assertion failure: