Skip to main content

Bust functools.lru_cache when running pytest to avoid test pollution

Project description

pytest-antilru

Build Status Coverage Status license Code style: black supported python versions pypi wheels pypi development status

Caching expensive function calls with functools.lru_cache is simple and great performance optimization. It works so well that it'll even speed up your unit test runs! Too bad it violated test isolation and caches the wrong values under test conditions, introducing test pollution (persisted state between test runs). This package will bust the lru_cache between test runs, avoiding test pollution and helping you keep your sanity.

Imagine you mock a network call out and your application ends up caching these mocked results:

def expensive_network_call() -> int:
    # Pretend this is an expensive network call.
    # You want to cache this for performance but you want to run tests with different responses as well.
    return 1


@lru_cache()
def cache_me() -> int:
    return expensive_network_call()

Now you have test pollution:

def test_a_run_first() -> None:
    assert cache_me() == 1


def test_b_run_second() -> None:
    # We want to mock the network call for this test case
    with mock.patch.object(sys.modules[__name__], 'expensive_network_call', return_value=2) as mock_network_call:
        assert cache_me() == 2
        assert mock_network_call.called

On your next test run, it doesn't matter what you mock, the results are already cached. Now trying running those two test out-of-order sequence and tell me how it goes.

Dependencies

Since this is a pytest plugin, you need to be using pytest to run your tests.

Compatibility

Starting from v2+, this project supports python 3.8+ and pytest 3+.

Older package releases exist to support python 2.7 to 3.7, from pytest 2-7.

While we aim to support a wide range of python and pytest combinations, pytest only supports the latest release: they do not patch older releases to work with newer python versions. See [tox.ini] for the full envlist of what is being tested.

If you experience issues, please check for compatibility between your python and pytest target versions. Open an issue once these are verified.

Installation

Simply install this in the same python environment that pytest uses and the rest is magic.

pip install pytest-antilru

Configuration

Add this where ever your pytest configurations live.

lru_cache_disabled

lru_cache_disabled is an allowlist of module paths to disable lru_cache for. This allows you to target disable caching for specific modules that are causing test pollution.

The default behaviour of pytest-antilru is to disable lru_cache everywhere. However, this can interfere with other dependencies that are reliant on lru_cache behaviour to behave correctly within the same test run.

[tool.pytest.ini_options]
lru_cache_disabled = '''
    my_module.util
    my_module.client_lib.database
    '''

In this example, any usage of lru_cache in a file inside my_module.util or my_module.client_lib.database will be disabled. All other instances will continue to be cached within a test run.

How to test the software

make test

Credits and references

This project was a re-engineering of a similar project a colleague of mine wrote. That project was not intended to be open-source and rather than go though all the hoops and hurdles to sanitize it, I've written it from the ground up such that it's kosher to open-source (given that it's such as small project).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytest_antilru-2.0.0.tar.gz (5.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytest_antilru-2.0.0-py3-none-any.whl (6.3 kB view details)

Uploaded Python 3

File details

Details for the file pytest_antilru-2.0.0.tar.gz.

File metadata

  • Download URL: pytest_antilru-2.0.0.tar.gz
  • Upload date:
  • Size: 5.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.4 Darwin/23.5.0

File hashes

Hashes for pytest_antilru-2.0.0.tar.gz
Algorithm Hash digest
SHA256 48cff342648b6a1ce4e5398cf203966905d546b3f2bee7bb55d7cb3ec87a85fb
MD5 ce0f87b2321a0ccefcde69cb977a914b
BLAKE2b-256 c6010b5ef3f143f335b5cb1c1e8e6497769dfb48aed5a791b5dfd119151e2b15

See more details on using hashes here.

File details

Details for the file pytest_antilru-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: pytest_antilru-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 6.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.4 Darwin/23.5.0

File hashes

Hashes for pytest_antilru-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cf1d97db0e7b17ef568c1f0bf4c89b8748053fe07546f4eb2558bebf64c1ad33
MD5 ca133a3cd2424355b7b7ab2a1b2c112f
BLAKE2b-256 23f0fc9f5aaaf2818a7d7f795e99fcf59719dd6ec5f98005e642e1efd63ad2a4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page