Skip to content

Seed test fixtures once per module instead of once per test - #2469

Merged
shangyian merged 2 commits into
mainfrom
test-perf-module-scoped-fixtures
Aug 28, 2026
Merged

Seed test fixtures once per module instead of once per test#2469
shangyian merged 2 commits into
mainfrom
test-perf-module-scoped-fixtures

Conversation

@shangyian

@shangyian shangyian commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

Some test fixtures are declared using @pytest.fixture with no scope, so it defaults to the function scope, which causes it to rerun the entire seeding sequence per test. That seeding sequence will recreate a series of nodes over HTTP, which can get expensive across dozens of tests (e.g., 6 node creations across 23 tests in the fan-out guard file, 7 tag creations across 10 tests in the tags GraphQL file etc).

This PR widens them to module scope and then points the tests at the module-scoped client. Since neither of these modules are mutating the seeded state (the fan-out tests only read through /sql/measures/v3/ and the tags tests issue read-only GraphQL queries), one seeding pass per module is sufficient.

When run locally:

fanout_guard_test.py  122.15s -> 56.14s
graphql/tags_test.py   53.64s -> 49.25s
transform_query_shapes_test.py   56.44s -> 51.79s

Test Plan

  • PR has an associated issue: #
  • make check passes
  • make test shows 100% unit test coverage

Deployment Plan

Two local fixtures created their nodes over HTTP on every test that used
them. Both were declared with a bare @pytest.fixture, so the default
function scope re-ran the whole seeding sequence per test -- 6 node
creations across 23 tests in the fan-out guard file, 7 tag creations
across 10 tests in the tags GraphQL file. Each POST re-parses and
re-validates SQL through the full app, so the repeats dominated those
modules.

Widen both to module scope and point them, and the tests that share
their data, at the module-scoped client. Neither module mutates the
seeded state -- the fan-out tests only read through /sql/measures/v3/
and the tags tests issue read-only GraphQL queries -- so one seeding
pass per module is equivalent.

fanout_guard_test.py  122.15s -> 56.14s (23 passed)
graphql/tags_test.py   53.64s -> 49.25s (10 passed)

Excluding the one-time template build those modules now spend 2.4s and
2.5s on setup, down from 68.3s and ~7s.
@netlify

netlify Bot commented Aug 28, 2026

Copy link
Copy Markdown

Deploy Preview for thriving-cassata-78ae72 canceled.

Name Link
🔨 Latest commit 8de8da4
🔍 Latest deploy log https://app.netlify.com/projects/thriving-cassata-78ae72/deploys/6a9195882602100008af3c0d

Same change as the fan-out and tags fixtures: client_with_edge_shapes
created four transforms over HTTP on each of its three consuming tests.
Nothing in the module mutates them, so one seeding pass per module is
equivalent.

transform_query_shapes_test.py  56.44s -> 51.79s (3 passed)
@shangyian
shangyian marked this pull request as ready for review August 28, 2026 21:26
@shangyian
shangyian merged commit eadbada into main Aug 28, 2026
21 checks passed
@shangyian
shangyian deleted the test-perf-module-scoped-fixtures branch August 28, 2026 21:26
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.

1 participant