Cache Behavior During Refactoring
Pytest does not automatically invalidate cache entries when a test function is renamed or moved. Because pytest keys its cache using the node ID (a combination of the file path and the function name), renaming a test creates a new node ID while leaving the stale data associated with the old ID intact in the .pytest_cache directory.
How Invalidation Works
Pytest primarily uses file modification timestamps (mtime) to determine if a cache is stale. If the timestamp of the test file is newer than the cache entry, pytest will typically refresh that data. However, a refactor that only changes a function name may not always trigger a timestamp update that pytest recognizes as a reason to purge specific node-keyed entries, leading to stale values being reused or orphaned data persisting in the cache.
Resolution Steps
To resolve stale cache issues after refactoring, use one of the following methods based on your needs:
Verification Process
You can verify if your cache is stale by running a collection-only pass before and after your refactor:
- Run
pytest --collect-only and note the listed node IDs.
- Rename a test function.
- Run
pytest --collect-only again. If the old node ID still appears or the new one isn't behaving as expected, the cache is stale.
- Execute
pytest --cache-clear and verify the IDs are now correct.
Assumptions and Constraints
This behavior is observed in Pytest 7.3.0. Note that while --cache-clear solves the staleness problem, it removes the performance benefits of caching (such as --lf for last-failed tests). If you are using pytest-xdist for parallel execution, be aware that all workers share the same cache directory, which can increase the likelihood of encountering race conditions or stale data during rapid refactoring cycles.
Diagnostic Detail: Are you using any third-party plugins that implement their own caching logic (e.g., pytest-dependency)? If so, the standard --cache-clear may not purge plugin-specific state.