Есть ли способ отключить дросселирование при использовании Pytest в Django?

Проблема:

Я хочу найти способ отключить дросселирование при запуске моих тестов с pytest -vv

Детали:

У меня есть эта политика дросселирования по умолчанию в моем settings.py файле:

  'DEFAULT_THROTTLE_RATES': {
        'anon': '100/day',
        'user': '1000/day'
    }

У меня также есть это приспособление в моем confest.py, которое возвращает ошибку всякий раз, когда я превышаю лимит запросов:

def get_token(user, client):
    response = client.post(
        "/email-login",
        {"email":user.email, "password": "B9vX95phJDi3C4"},
    )
    return {
        "HTTP_AUTHORIZATION": f"Bearer {response.json()['token']['access']}"
    }

Что я пробовал:

Я попытался использовать решение в этом выпуске на GitHub: https://github.com/encode/django-rest-framework/issues/1336, но оно не работает в моем случае.

Сначала вам нужно создать способ различать тестовые среды и другие. Как мы делаем для PROD и DEV, используя settings.DEBUG config.

Моя рекомендация - создать переменную env test=True и затем в вашей settings.py написать -

if os.environ.get("test", False):
   REST_FRAMEWORK = {
     'DEFAULT_THROTTLE_CLASSES': [
    'rest_framework.throttling.AnonRateThrottle',
    'rest_framework.throttling.UserRateThrottle'
  ],
  'DEFAULT_THROTTLE_RATES': {
    'anon': '100/day',
    'user': '1000/day'
   }
}

иначе он ничего не делает, и drf не будет дросселировать.

Мне удалось решить эту проблему с помощью следующих шагов:

  • Я создал новый файл настроек, который наследовался от базового файла настроек. т.е. from settings import *
  • Затем я удалил ключ DEFAULT_THROTTLE_RATES, т.е. del REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]
  • Далее я указал на новый файл настроек в pytest.ini т.е. DJANGO_SETTINGS_MODULE="new_settings.py"

Теперь тесты будут использовать новый файл настроек

@ra123 в целом имеет правильную идею. В качестве другого подхода, во всех проектах Django я добавляю что-то вроде этого в settings/__init__.py (или просто settings.py, если вы делаете один файл). Оно смотрит на argv, чтобы определить, находится ли он в тестовом режиме

IS_TESTING = bool(set(sys.argv[:2]) & {"pytest", "test", "jenkins"})

REST_FRAMEWORK = { "YOUR_CONFIG": "..." }

# at the very very end, AFTER your settings are loaded:
if IS_TESTING:
    # override your rest framework settings in test mode
    REST_FRAMEWORK["DEFAULT_THROTTLE_CLASSES"] = []

    # some other handy things, for making tests faster/easier
    PASSWORD_HASHERS = ("django.contrib.auth.hashers.MD5PasswordHasher",)
    EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
    DEFAULT_FILE_STORAGE = "inmemorystorage.InMemoryStorage"

Я решил сделать это таким образом, чтобы не беспокоиться о том, что он когда-нибудь получит неправильные настройки. Это также помогает держать все централизованно, так что (например) вы не вызываете sentry.init в режиме тестирования, даже если в окружении есть sentry_url.

Вернуться на верх