diff --git a/README.md b/README.md index daeaa9be..86e35801 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ git submodule update --remote ### Testing -The test suite in this project was specifically built to produce consistent results on every run, regardless of when they run or who is running them. This project uses [VCR](https://github.com/kevin1024/vcrpy) to record and replay HTTP requests and responses via "cassettes". When the suite is run, the HTTP requests and responses for each test function will be saved to a cassette if they do not exist already and replayed from this saved file if they do, which saves the need to make live API calls on every test run. +The test suite in this project was specifically built to produce consistent results on every run, regardless of when they run or who is running them. This project uses [VCR](https://github.com/kevin1024/vcrpy) to record and replay HTTP requests and responses via "cassettes". When the suite is run, the HTTP requests and responses for each test function will be saved to a cassette if they do not exist already and replayed from this saved file if they do, which saves the need to make live API calls on every test run. If you receive errors about a cassette expiring, delete and re-record the cassette to ensure the data is up-to-date. **Sensitive Data:** We've made every attempt to include scrubbers for sensitive data when recording cassettes so that PII or sensitive info does not persist in version control; however, please ensure when recording or re-recording cassettes that prior to committing your changes, no PII or sensitive information gets persisted by inspecting the cassette. diff --git a/tests/conftest.py b/tests/conftest.py index 3e016dd6..6decb7df 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,7 @@ +import datetime import json import os +import warnings from typing import ( Any, Dict, @@ -69,6 +71,25 @@ def partner_prod_api_key(): easypost.api_key = default_key +@pytest.fixture(autouse=True) +def check_expired_cassettes(expiration_days: int = 180, throw_error: bool = False): + """Checks for expired cassettes and throws errors if they are too old and must be re-recorded.""" + test_name = os.environ.get("PYTEST_CURRENT_TEST").split(":")[-1].split(" ")[0] # type: ignore + cassette_filepath = os.path.join("tests", "cassettes", f"{test_name}.yaml") + + if os.path.exists(cassette_filepath): + cassette_timestamp = datetime.datetime.fromtimestamp(os.stat(cassette_filepath).st_mtime) + expiration_timestamp = cassette_timestamp + datetime.timedelta(days=expiration_days) + current_timestamp = datetime.datetime.now() + + if current_timestamp > expiration_timestamp: + error_message = f"{cassette_filepath} is older than {expiration_days} days and has expired. Please re-record the cassette." # noqa + if throw_error: + raise Exception(error_message) + else: + warnings.warn(error_message) + + @pytest.fixture(scope="session") def vcr_config(): """Setup the VCR config for the test suite.""" diff --git a/tests/test_event.py b/tests/test_event.py index cb1d30ff..14b143dd 100644 --- a/tests/test_event.py +++ b/tests/test_event.py @@ -24,7 +24,6 @@ def test_event_retrieve(page_size): assert str.startswith(event.id, "evt_") -@pytest.mark.vcr() def test_event_receive(event_json): event = easypost.Event.receive(event_json)