beets/test
Šarūnas Nejus 3b670cdf18
In test I/O utility, restore the old stdin/stdout instead of the "true" I/O streams (#5049)
I got a little bit nerdsniped by the problems observed in #5027. In
short, my high-level diagnosis in
https://github.com/beetbox/beets/pull/5027#issuecomment-1857953929 seems
to have been correct: other tests were suppressing the legitimate
failure of a flaky test.

I found the problem by running other tests before the problem test, like
this:

```
$ pytest -k 'test_nonexistant_db or test_delete_removes_item' test/test_ui.py
```

When running `test_nonexistant_db` alone, it fails. When running it like
this with another test that goes first, it passes. That's the problem.

However, `test_delete_removes_item` is just one example that works to
make this problem happen. It appeared that _any_ test in a class that
used our `_common.TestCase` base class had this power. I tracked down
the issue to our `DummyIO` utility, which was having an unintentional
effect even when it was never actually used.

Here's the solution. Instead of restoring `sys.stdin` to
`sys.__stdin__`, we now restore it to whatever it was before we
installed out dummy I/O hooks. This is relevant in pytest, for example,
which installs its *own* `sys.stdin`, which we were then clobbering.
This was leading to the suppression of test failures observed in #5021
and addressed in #5027.

The CI will fail for this PR because it now (correctly) exposes a
failing test. Hopefully by combining this with the fixes in the works in
#5027, we'll be back to a passing test suite. 😃 @Phil305, could
you perhaps help validate that hypothesis?

Edit: @snejus:

I've now consolidated test I/O handling by removing the legacy
`control_stdin`/`capture_stdout` context managers and the custom
`DummyOut` stream, replacing them with a pytest-driven `io` fixture
that:
- provides controllable `stdin` via a lightweight `DummyIn`
- captures `stdout` via `capteesys`
- attaches a `DummyIO` helper to test classes as `self.io`
2026-02-14 18:03:34 +00:00
..
autotag Enable RUF rules 2026-01-13 20:55:40 +00:00
plugins In test I/O utility, restore the old stdin/stdout instead of the "true" I/O streams (#5049) 2026-02-14 18:03:34 +00:00
rsrc musicbrainz: lookup release directly 2025-12-20 01:35:51 +00:00
ui Replace capture_output with io.getoutput 2026-02-10 00:53:20 +00:00
util Enable RUF rules 2026-01-13 20:55:40 +00:00
__init__.py
conftest.py Replace custom stdio mocks with pytest io fixture 2026-02-10 00:53:20 +00:00
test_art_resize.py Enable RUF rules 2026-01-13 20:55:40 +00:00
test_autotag.py Define a shared fixture for config 2025-12-27 14:30:35 +00:00
test_datequery.py
test_dbcore.py Merge branch 'master' into indices 2026-01-30 01:03:18 +00:00
test_files.py reflink() doesn't take Path parameters 2025-11-23 13:50:57 -04:00
test_hidden.py
test_importer.py
test_library.py Enable RUF rules 2026-01-13 20:55:40 +00:00
test_logging.py fix: Sanitize log messages by removing control characters 2025-12-02 15:27:24 +05:00
test_m3ufile.py
test_metadata_plugins.py Simplify tests 2026-01-31 23:42:09 +00:00
test_metasync.py Replace capture_output with io.getoutput 2026-02-10 00:53:20 +00:00
test_pipeline.py
test_plugins.py Replace capture_output with io.getoutput 2026-02-10 00:53:20 +00:00
test_query.py
test_release.py Improve reference title for command links 2026-02-08 07:28:09 +00:00
test_sort.py pyupgrade Python 3.10 2025-11-08 12:09:52 +00:00
test_template.py
test_types.py
test_util.py
testall.py