Django에서 다른 설정으로 단위 테스트하는 방법은 무엇입니까?
단위 테스트를 위해 Django 재정의하는 간단한 구현을 실행합니까? 특정 수의 최신 개체를 반환하는 내 모델 중 하나에 관리자가 있습니다. 반환되는 개체 수는 NUM_LATEST 설정에 의해 정의됩니다.
내 테스트가 설정을 변경할 가능성이 있습니다. 설정을 나중에 복원 setUp()
하고 복원 먼저 tearDown()
해야합니까? 그것이 가능하지 않다면 원숭이 패치 방법이나 설정을 모의 할 수있는 방법이 있습니까?
편집 : 내 관리자 코드는 다음과 달라집니다.
class LatestManager(models.Manager):
"""
Returns a specific number of the most recent public Articles as defined by
the NEWS_LATEST_MAX setting.
"""
def get_query_set(self):
num_latest = getattr(settings, 'NEWS_NUM_LATEST', 10)
return super(LatestManager, self).get_query_set().filter(is_public=True)[:num_latest]
관리자는 settings.NEWS_LATEST_MAX
쿼리 세트를 분할하는 데 관리자 사용 합니다. 는 getattr()
기본 제공되는 데 사용됩니다.
편집 :이 대답 은 약간 의 특정 테스트에 대한 설정을 변경하려는 경우 적용 됩니다.
Django 1.4부터 테스트 중에 설정을 재정의하는 방법이 있습니다. https://docs.djangoproject.com/en/dev/topics/testing/tools/#overriding-settings
TestCase는 self.settings 많은 관리자가 대규모 테스트 메서드 또는 전체 TestCase 하위 클래스에 적용 할 수있는 @override_settings 데코레이터도 있습니다.
Django 1.3에 아직 존재하지 않습니다.
모든 테스트에 대한 설정을 변경하고 기본 설정 파일에서 설정을로드하고 재정의 할 수있는 별도의 테스트 설정 파일을 전달합니다. 다른 답변에는 이에 대한 몇 가지 좋은 접근 방식이 있습니다. 나는 hspander 와 dmitrii의 접근 방식 모두에서 성공적인 변형을 보았습니다 .
UnitTest
인스턴스 속성 설정 및 읽기를 포함 하여 하위 클래스에 대해 원하는 모든 작업을 수행 할 수 있습니다 .
from django.conf import settings
class MyTest(unittest.TestCase):
def setUp(self):
self.old_setting = settings.NUM_LATEST
settings.NUM_LATEST = 5 # value tested against in the TestCase
def tearDown(self):
settings.NUM_LATEST = self.old_setting
그러나 django 테스트 케이스는 하나의 단일로 실행되기 때문에 NUM_LATEST 값을 수정하는 다른 항목이 궁금합니다. 그 "다른 것"이 당신의 테스트 루틴에 의해 촉발 딱, 나는 어떤 양의 원숭이 패치가 테스트 자체의 진실성을 무효화하지 않고 테스트를 확신하지 못합니다.
업데이트 : 아래 솔루션은 Django 1.3.x 및 이전 버전에서만 필요합니다. > 1.4의 경우 slinkp의 답변을 참조하십시오 .
테스트에서 설정을 자주 변경하고 Python ≥2.5를 사용하는 경우이 방법도 편리합니다.
from contextlib import contextmanager
class SettingDoesNotExist:
pass
@contextmanager
def patch_settings(**kwargs):
from django.conf import settings
old_settings = []
for key, new_value in kwargs.items():
old_value = getattr(settings, key, SettingDoesNotExist)
old_settings.append((key, old_value))
setattr(settings, key, new_value)
yield
for key, old_value in old_settings:
if old_value is SettingDoesNotExist:
delattr(settings, key)
else:
setattr(settings, key, old_value)
그런 다음 다음을 수행 할 수 있습니다.
with patch_settings(MY_SETTING='my value', OTHER_SETTING='other value'):
do_my_tests()
--settings
테스트를 선택할 때 옵션 을 선택할 수 있습니다.
python manage.py test --settings=mysite.settings_local
구성을 구성을 재정의하는 것이 도움이 될 수 있습니다 제 생각에 테스트를 위해 별도의 파일을 재정합니다. 이렇게하면 테스트를위한 많은 구성이 저장되고, 이는 복구 할 수없는 작업 (예 : 스테이징 데이터베이스 정리)을 수행하지 않습니다.
테스트 파일이 'my_project / test_settings.py'에 어디에서 가정하고
settings = 'my_project.test_settings' if 'test' in sys.argv else 'my_project.settings'
manage.py에서. 이렇게하면 실행할 때 python manage.py test
test_settings 만 사용할 수 있습니다. pytest와 같은 다른 테스트 클라이언트를 사용하는 경우 쉽게 pytest.ini에 추가 할 수 있습니다.
@override_settings
프로덕션 환경과 테스트 환경 구성 사이에 차이가 많지 않은 경우 유용합니다.
다른 경우에는 다른 설정 파일을 사용하는 것이 좋습니다. 이 경우 프로젝트는 다음과 같습니다.
your_project
your_app
...
settings
__init__.py
base.py
dev.py
test.py
production.py
manage.py
따라서 대부분의 설정 base.py
이 있어야하며 다른 파일에서 모든 것을 가져 와서 일부 옵션을 재정의해야합니다. 여기 무슨 test.py
파일이 다음과 같이 표시됩니다
from .base import *
DEBUG = False
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'app_db_test'
}
}
PASSWORD_HASHERS = (
'django.contrib.auth.hashers.MD5PasswordHasher',
)
LOGGING = {}
그런 다음 --settings
@MicroPyramid 답변에서와 같이 옵션 을 지정 하거나 DJANGO_SETTINGS_MODULE
환경 변수를 지정한 다음 테스트를 실행할 수 있습니다.
export DJANGO_SETTINGS_MODULE=settings.test
python manage.py test
일부 doctest를 수정하는 동안이 문제를 발견했습니다 ... 완전성을 위해 doctest를 사용할 때 설정을 수정하려면 다른 항목을 가져 오기 전에 수정해야합니다.
>>> from django.conf import settings
>>> settings.SOME_SETTING = 20
>>> # Your other imports
>>> from django.core.paginator import Paginator
>>> # etc
pytest를 사용하고 있습니다.
나는 이것을 다음과 같은 방법으로 해결했습니다.
import django
import app.setting
import modules.that.use.setting
# do some stuff with default setting
setting.VALUE = "some value"
django.setup()
import importlib
importlib.reload(app.settings)
importlib.reload(modules.that.use.setting)
# do some stuff with settings new value
다음과 같이 테스트의 설정을 재정의 할 수 있습니다.
from django.test import TestCase, override_settings
test_settings = override_settings(
DEFAULT_FILE_STORAGE='django.core.files.storage.FileSystemStorage',
PASSWORD_HASHERS=(
'django.contrib.auth.hashers.UnsaltedMD5PasswordHasher',
)
)
@test_settings
class SomeTestCase(TestCase):
"""Your test cases in this class"""
다른 파일에서 이러한 동일한 설정이 필요한 경우 test_settings
.
하위 디렉토리 (python 패키지)에 여러 테스트 파일이있는 경우 sys.argv에 'test'문자열이 있는지 조건에 따라 이러한 모든 파일에 대한 설정을 재정의 할 수 있습니다.
app
tests
__init__.py
test_forms.py
test_models.py
__init__.py :
import sys
from project import settings
if 'test' in sys.argv:
NEW_SETTINGS = {
'setting_name': value,
'another_setting_name': another_value
}
settings.__dict__.update(NEW_SETTINGS)
최선의 방법은 아닙니다. Celery 브로커를 Redis에서 Memory로 변경하는 데 사용했습니다.
참고 URL : https://stackoverflow.com/questions/913549/how-to-unit-test-with-different-settings-in-django
'IT' 카테고리의 다른 글
잡히지 않은 TypeError : undefined는 jquery-min.js로드시 함수가 아닙니다. (0) | 2020.08.14 |
---|---|
Mac OS X Leopard 키 바인딩의 Emacs (0) | 2020.08.14 |
.NET의 URL에서 페이지를 읽는 가장 쉬운 방법 (0) | 2020.08.14 |
PHP의 배열에서 쉼표로 구분 된 목록을 어떻게 생성합니까? (0) | 2020.08.14 |
C ++ 용 온라인 이름 demangler가 있습니까? (0) | 2020.08.14 |