-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Output appears in "Captured stderr call" but is unavailable in capsys or capfd #5997
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
this is pretty strange, it probably should work with the test passes with |
Oh yeah, passing -s and using |
Related (I think): #3448 |
This is just for
and
then only the third assertion fails. Currently looking into this |
@MarcoGorelli |
Just as an update - I've been studying Else I'll keep hacking away :) |
I'm seeing this issue with |
It seems that the bug described in pytest-dev/pytest#5997 is preventing stderr to be captured by capsys. The workaround consists in using both `capfd` and `--capture=tee-sys` (or just `-s`).
It seems that the bug described in pytest-dev/pytest#5997 is preventing stderr to be captured by capsys. The workaround consists in using both `capfd` and `--capture=tee-sys` (or just `-s`).
Capture logs may fail on OSX, not sure if this also happen on other Os, to avoid this we replace capsys fixture by capfd, and use pytest '-s' See also: pytest-dev/pytest#5997 New test rules added o TestCreateAddDecodeFromWithSymlinks o test_everything_succeed_when_no_broken_symlinks o test_add_exit_code_0_even_when_broken_symlinks o test_add_creates_keys_for_all_non_broken_symlinks o test_can_decode_keys_of_non_broken_symlinks o test_warn_about_broken_symlinks
Workaround for capsys, capfd failure during capture logging See also: pytest-dev/pytest#5997
I suspect it might be related to: pytest-dev/pytest#5160 pytest-dev/pytest#5997
@MarcoGorelli did you ever figure this one out? I just ran into the same problem and found this issue :). |
Nope, I gave up on this 😳 |
I am also having this issue. Would like to be able to use |
I have a simpler reproduction that only succeeds with import sys
x = sys.stdout.buffer
def test(capfd):
x.write(b'wat\n')
x.flush()
assert capfd.readouterr().out |
@RonnyPfannschmidt my reproduction above does not use logging -- this is definitely something |
ok so I took a bit of a look at this on stream. I can get it to do what I want by disabling the I have a bit of a work-in-progress version of this branch, but it requires a lot of changes to the testsuite (not sure whether it's actually a good change or not given how many tests it broke?) -- I also have to change a lot of tests to run in a subprocess so they don't interfere with the tests themselves (because syscapture is no longer being reset) here's that patch though, or at least the start of it: https://github.com/pytest-dev/pytest/pull/new/wip_fix_capfd |
I am wondering what happend with this @asottile ? |
I got busy and never got around to finishing that branch above -- I also wasn't 100% on whether it's ultimately the right decision (since the test adjustments really point out how much it potentially would break consumers) |
I understand. turning off the syscapture part maybe does not really make sense and this needs a different solution? |
I think I ran into the same issue, my repro: # foo.py
print("hello") Surprisingly: from importlib import import_module
def test_prints_hello(capfd):
import_module('foo')
out, err = capfd.readouterr()
assert out == "" # will pass
# assert out == "hello\n" # and so will this one (expected), but only if above line is commented out edit Although this is still happening in the particular project I used, I'm not able to reproduce this in an fresh & independent venv. Very strange... |
I've bumped into this, too. The
And as was noted above, the test passes when using |
Any reason why it is not possible to pass a logger instance to pytest's caplog? The only option is to give a logger name. However, that does not work in some cases as seen in this long thread. And capsys or capfd is not what I need either. In unittest assertLogs it is possible to give a logger. Just wonder why it wasn't done similarly in pytest. For the record, what I ended up doing was the following context manager: @contextmanager
def capture_logs(logger: logging.Logger):
with ExitStack() as stack:
captured = StringIO()
for handler in logger.handlers:
if isinstance(handler, logging.StreamHandler):
stack.enter_context(patch.object(handler, "stream", captured))
yield captured And then in a test: with capture_logs(logger_being_tested) as logs:
...
assert ... in logs.getvalue() |
Add this snippet to
But why it is so hard to fix it in passed 3 years? |
if it's so easy why don't you fix it? |
@asottile You're not helping by lashing out at people. You could have constructively encouraged them to provide input on fixing this issue instead. |
i think we need to split this issue a bit - the initial issue is no longer valid - configuring logging with just the defaults is broken and non-fixable + disables pytests logcapture logcapture fixtures should be used logging should onl be configured by an application, not for testrunning pytest will not do logcapture if logging is configured as the footguns from the past still haunt me at least |
I got the same unexpected behavior of capsys in my project . After going through this discussion I tried the following approaches:
Since I don't want to make a global change in my project's pytest configuration I am more biased towards an approach which wouldn't need global setting, like the marker approach. Is there a better way to do this? |
I ran into an issue where I was expecting this test to pass: <some code that logs stuff>
...
out, err = capsys.readouterr()
assert len(out) > 0 Where the following code failed: from sys import sysout as sys_stdout
...
console_handler = StreamHandler(sys_stdout)
console_handler.setFormatter(formatter)
console_handler.setLevel(self._log_level)
self._logger.addHandler(console_handler) But this passed: import sys
...
console_handler = StreamHandler(sys.stdout)
console_handler.setFormatter(formatter)
console_handler.setLevel(self._log_level)
self._logger.addHandler(console_handler) I haven't had a chance to look into why this might be the case but I figure I'll put this here in case other people run into a similar issue. Before arriving at this solution, I tried the |
Never use non lazy/recomputed references to sys.stdout Studio recapture replaces those and closes old ones dozens of times |
I ran into the problem of capsys/capfd not capturing log entries if the log was written to sys.stdout by a StreamHandler while also writing to file. All other solutions in this thread (and many others) did not work, so I wanted to highlight this also in conclusion with the setup I am needing (which I also did not found yet in issues). File
file
So I got a workaround. But using fixtures would be better, as they are basically also context managers. Passing data to fixtures is possible with markers and the request fixture, so I modified my tests accordingly.
Edit 1: Formatting issues resolved |
Environment
Pytest version: 5.2.1
Operating system: Kubuntu 18.04.3 LTS
Pip list:
Description
It seems that output can appear in "Captured stderr call" but be unavailable to capsys or capfd, which can be a bug? It's definitely weird.
I came accross this issue while trying to test my logging setup. This is a minimal example I came up with (available at https://github.com/butla/experiments/tree/master/pytest_capture_log_error):
The test fails and it shows
but both
capsys
andcapfd
showout
anderr
to be empty.I would use caplog, but the messages I get from it don't conform to the log configuration that I have set up in my original app, so I decided to just use stderr.
The text was updated successfully, but these errors were encountered: