-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Logging StreamHandler fails when set up in fixture with capsys #10486
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
Comments
It's a expected breakage with output capture that cleans up after itself, use log capture directly |
Using the log capture would not test what we wish to test. We have an elaborate logging setup with structured logging (JSON) and wish to test that the application is configured to log properly. I did not include this in the minimal example. If this is expected breakage, then that expectation is not communicated at all. I'm surprised by this because all fixtures I've used up to this point do some work to return a value, and then they may do some work when the test is done running. In the case of |
For most tests, I think it's fine to use the log capture fixture to test what is logged. For the one test that tests whether the log handlers are set up correctly, I'll just do the setup inside the test itself and not in a fixture, so that There may be good reasons for Perhaps |
We are noticing the exact same issue implementing tests for our JSON logging to stdout using the capsys fixture. |
I recommend using a stream handler that dynamically fetches the stream |
Thanks for the suggestion. It inspired toward this approach. I'm not sure if this is what you meant exactly, but I'll share a gist: Logging setup BASE_LOG_HANDLER = logging.StreamHandler(sys.stdout)
logging.root.handlers = [BASE_LOG_HANDLER] Test fixture @pytest.fixture
def mock_log(app):
with mock.patch.object(BASE_LOG_HANDLER.stream, "write") as _mock_log:
yield _mock_log Test def test_base_log_handler(mock_log):
logging.root.debug("test")
assert "test\n" in mock_log.call_args.args |
Bug description
I'm running into an issue where an instance of
logging.StreamHandler
fails to write to its assigned stream, but only when we initialise it in a fixture. If we initialise it inside the test itself, it works as expected.It seems to me that the issue here is the value of
sys.stdout
. It seems to change some time between the fixtures being run and the test itself running. WhenStreamHandler
is set up during a fixture, we give it a value ofsys.stdout
which is later closed, sincesys.stdout
is superseded by a new value.Expected behaviour
I thought I could just move my setup code to a fixture instead of needing to call the setup code in every test, without any big changes to how that setup code is run. In my thinking,
capsys
will do its magic withsys.stdout
when it is run, so that when I create fixtures that depend oncapsys
,sys.stdout
should already be set to the value it will have during the test (since that is how any other user-created fixture works).Minimal example with StreamHandler
Minimal example:
test_with_setup_in_test
passes, whiletest_with_setup_in_fixture
fails. Its error message:Minimal example demonstrating that sys.stdout changes
The test fails.
Interestingly, this test passes if I remove
capsys
.My environment
Output of
pip list
:I'm running Ubuntu 20.0.5 in Windows Subsystem for Linux
The text was updated successfully, but these errors were encountered: