Skip to content

tests: replace function-scoped helper fixtures with TestHelper#6709

Open
snejus wants to merge 7 commits into
masterfrom
migrate-helper-test-classes
Open

tests: replace function-scoped helper fixtures with TestHelper#6709
snejus wants to merge 7 commits into
masterfrom
migrate-helper-test-classes

Conversation

@snejus

@snejus snejus commented Jun 4, 2026

Copy link
Copy Markdown
Member
  • Test setup was consolidated into shared helper classes instead of using local helper fixtures.
  • test/library/test_migrations.py now uses MigrationTestHelper to provide one common migration harness, with each test class defining only the legacy state and migration it needs.
  • Plugin tests in test/plugins/test_fuzzy.py, test/plugins/test_missing.py, and test/plugins/utils/test_playcount.py now rely on shared helpers like PluginTestHelper and TestHelper for common setup.

Note: I kept these fixtures in these files

  • test_query.py
  • plugins/test_random.py
  • plugins/test_aura.py
  • plugins/test_lyrics.py

because they intentionally use a higher scope, for example in test_query.py:

@pytest.fixture(scope="class")
def helper():
    helper = TestHelper()
    helper.setup_beets()

    yield helper

    helper.teardown_beets()

Using this setup pattern in test_query.py significantly improved testing durations.

Architecture impact

  • Test infrastructure now follows a clearer base-class pattern for shared setup.
  • Migration tests cleanly separate 'prepare old state' from 'run migration and verify result'.
  • Plugin tests now use the same setup path, which makes new tests easier to add and keeps test structure more consistent across files.

High-level outcome

  • Less duplicated fixture boilerplate.
  • More consistent and easier-to-read test architecture.
  • Tests stay focused on behavior being verified, which should make maintenance and future extension simpler.

Copilot AI review requested due to automatic review settings June 4, 2026 22:26
@snejus snejus requested a review from a team as a code owner June 4, 2026 22:26
@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

Thank you for the PR! The changelog has not been updated, so here is a friendly reminder to check if you need to add an entry.

@codecov

codecov Bot commented Jun 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.71%. Comparing base (60047df) to head (3f4d9d5).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #6709      +/-   ##
==========================================
+ Coverage   74.52%   74.71%   +0.18%     
==========================================
  Files         162      162              
  Lines       20818    20818              
  Branches     3295     3295              
==========================================
+ Hits        15515    15554      +39     
+ Misses       4547     4505      -42     
- Partials      756      759       +3     

see 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

grug see PR make test setup less copy-paste. instead of local helper fixtures per file, tests now inherit shared helper classes (TestHelper/PluginTestHelper) and migration tests get one common harness.

Changes:

  • swap function-scoped helper fixtures for TestHelper / PluginTestHelper base classes in plugin tests
  • add MigrationTestHelper harness so each migration test only defines legacy setup + migration under test
  • adjust playcount tests to use class-based helper + explicit log fixture injection

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
test/plugins/utils/test_playcount.py move from helper fixture to TestHelper inheritance; pass logger via fixture
test/plugins/test_missing.py use shared PluginTestHelper (plus IO mixin) for missing plugin CLI tests
test/plugins/test_fuzzy.py use PluginTestHelper for fuzzy plugin tests; remove local helper fixture
test/library/test_migrations.py introduce MigrationTestHelper and refactor migrations tests onto shared harness

Comment thread test/library/test_migrations.py
@snejus snejus force-pushed the migrate-helper-test-classes branch 5 times, most recently from 9080832 to 2ad2368 Compare June 11, 2026 19:43
snejus added 4 commits June 16, 2026 08:46
- Replace local setup fixtures with existing test helper base classes to reduce
  duplicated test setup.
- Centralize migration test setup in a shared helper and update the migration
  tests to use the common pre-migration initialization flow.
- This removes repeated fixture boilerplate while keeping each test focused on
  the migration behavior it verifies.
- Replace duplicate pytest import helper fixtures with PluginMixin-based setup
  helpers.
- Keep plugin import tests aligned with shared beets setup behavior.
@snejus snejus force-pushed the migrate-helper-test-classes branch from 2ad2368 to 980d256 Compare June 16, 2026 07:48
@snejus snejus requested a review from Copilot June 16, 2026 07:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 1 comment.

Comment thread beets/test/helper.py Outdated
snejus added 3 commits June 16, 2026 12:32
- Dropped unused MusicBrainZ and Subsonic test helpers and imports.
- Keeps plugin test modules focused on the behavior they still exercise.
@snejus snejus force-pushed the migrate-helper-test-classes branch from 980d256 to 3f4d9d5 Compare June 16, 2026 11:32

@semohr semohr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the introduction of these <scope>_helper fixtures in general. I'm just not entirely sure how the scopes were chosen based on where the fixtures are actually used. To me, it looks like most of them could probably use session scope. 🤔

I did a quick experiment and changed the fixture in test_random to session, and I didn't run into any issues. Maybe there's a reason for the more restrictive scopes that I'm missing?

Comment thread test/plugins/test_aura.py
helper.setup_beets()
yield helper
helper.teardown_beets()
@pytest.fixture(scope="session")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the indirection? Couldn't we use session_helper directly?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indirection is intentional: it keeps each test module using the stable local helper fixture name while delegating lifecycle/scope to the shared helper fixtures. That means the rest of the module does not need to know whether the backing helper is session-, module-, or class-scoped.

If we used session_helper directly, that scope detail would spread through the module and future scope changes would require broader fixture/test renames. With this shape, changing scope requires adjusting these 3 lines only:

@pytest.fixture(scope="session")
def helper(session_helper):
    return session_helper

helper.setup_beets()
yield helper
helper.teardown_beets()
def helper(module_helper):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here again some unneeded indirection imo. Im also wondering now why we need the helper on different scopes in the first place. Have you tried session scope here? Do we have sideffect here which we dont want to propagate to the session scope?

Comment thread test/conftest.py
return check_import


@pytest.fixture(scope="session")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we add a bit of doc strings here on when we expect them to be used?

@semohr semohr mentioned this pull request Jun 16, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants