Skip to content

Refactor integration tests to share assertions and reduce API calls - #160

Merged
sergioteula merged 4 commits into
masterfrom
claude/integration-tests-optimization-glrbyu
Sep 4, 2026
Merged

Refactor integration tests to share assertions and reduce API calls#160
sergioteula merged 4 commits into
masterfrom
claude/integration-tests-optimization-glrbyu

Conversation

@sergioteula

Copy link
Copy Markdown
Owner

Summary

This PR refactors the integration test suites for both sync and async clients to eliminate code duplication and significantly reduce the number of API calls made during testing. The changes extract shared test logic into a new integration_support.py module that both test suites inherit from, while restructuring how API calls are made and cached.

Key Changes

  • New tests/integration_support.py module: Contains all shared integration test infrastructure including:

    • Credentials and ApiSnapshot dataclasses for managing test data
    • IntegrationAssertions base class with 20+ shared test methods
    • Helper functions for credential loading, item filtering, and ASIN selection
    • Constants defining the request budget and skip messages
  • Refactored sync test suite (tests/amazon_creatorsapi/integration_test.py):

    • Reduced from 473 to 170 lines by inheriting from IntegrationAssertions
    • Moved API call orchestration into collect_snapshot() function
    • Uses setUpClass to collect snapshot once, then all tests read from cache
    • Removed duplicate helper methods and assertions
  • Refactored async test suite (tests/amazon_creatorsapi/aio/integration_test.py):

    • Reduced from 469 to 178 lines with same inheritance pattern
    • Async version of collect_snapshot() that manages connection pooling
    • Maintains async/await patterns while sharing assertion logic
  • Optimized API call strategy:

    • Search call now serves as discovery for subsequent calls (ASINs, browse nodes, variations)
    • Single get_items call mixes URLs, duplicates, and missing ASINs to test parsing and error handling
    • Feeds and reports calls gracefully skip when credentials lack access
    • Token refresh and connection release tested as side effects of existing calls

Notable Implementation Details

  • Both test suites now make at most 8 API calls total (down from ~20+ per suite)
  • Shared assertions ensure sync and async clients maintain the same contract
  • ApiSnapshot dataclass caches all results, allowing tests to run without network access
  • Helper functions like pick_item_asins() and build_item_ids() encapsulate the logic for selecting test data
  • Credentials loading centralized with fallback to environment variables via dotenv
  • Tests skip gracefully when credentials lack access to specific features (feeds, reports)

https://claude.ai/code/session_017ZLhDcp9SziFvYduax9evq

The integration suites only reached search_items, get_items, get_variations
and get_browse_nodes, and each one wrote its own assertions, so the sync and
the async clients were not held to the same contract and feeds and reports
were never checked against the real API.

Both suites now share tests/integration_support.py, which holds the
credentials, the snapshot of the results and every assertion, and each suite
only builds its client and makes the calls. The calls carry as much as they
can instead of being repeated:

- The search is also the discovery call, and asks with an availability, a
  condition and a sort so the request is validated by Amazon as well.
- A single get_items mixes a URL, a duplicate and an unknown identifier, so
  one request checks the parsing of URLs, the removal of duplicates, the
  order of the answer, its partial errors and the placeholders added by
  include_unavailable.
- Variations and browse nodes reuse the parent ASIN and the node identifiers
  of the search, and are skipped instead of asked for when the search found
  none, so no request is spent on a call known to fail.
- Feeds and reports are listed and downloaded, reporting an account without
  access to them as a skip instead of failing the suite.
- Releasing the connections, dropping the token and using the async client
  outside its context manager are folded into the calls above, so they cost
  no request of their own.

The async suite also stops making its calls while the module is imported,
which ran them even when the tests were deselected and turned a failure into
a collection error, and it no longer spends an extra search on checking its
context manager.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ZLhDcp9SziFvYduax9evq
Both branches added entries to the Unreleased section of the changelog, so
the ones of the documentation review and the ones of the integration tests
are kept together.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ZLhDcp9SziFvYduax9evq
The name-tests-test hook asks every file under tests to be named after the
pattern of a test module, and tests/integration_support.py is the support
shared by both integration suites, holding no test of its own.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ZLhDcp9SziFvYduax9evq
@sergioteula
sergioteula merged commit bdcc4d9 into master Sep 4, 2026
7 checks passed
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.

2 participants