[python] Django의 테스트 데이터베이스를 메모리에서만 실행하는 방법은 무엇입니까?
내 Django 단위 테스트는 실행하는 데 오랜 시간이 걸리므로 속도를 높이는 방법을 찾고 있습니다. SSD 설치를 고려하고 있지만 단점도 있다는 것을 알고 있습니다. 물론 내 코드로 할 수있는 일이 있지만 구조적 수정을 찾고 있습니다. 매번 데이터베이스를 다시 빌드 / 마이그레이션해야하기 때문에 단일 테스트를 실행하는 것조차 느립니다. 그래서 여기 내 생각이 있습니다.
테스트 데이터베이스가 항상 매우 작다는 것을 알고 있기 때문에 전체 테스트 데이터베이스를 항상 RAM에 유지하도록 시스템을 구성 할 수없는 이유는 무엇입니까? 디스크를 절대 만지지 마십시오. Django에서 어떻게 구성합니까? 나는 그것이 내가 프로덕션에서 사용하는 것이므로 MySQL 을 계속 사용하는 것을 선호 하지만 SQLite 3 또는 다른 것들이 이것을 쉽게 만든다면 나는 그렇게 할 것입니다.
SQLite 또는 MySQL에 완전히 메모리에서 실행할 수있는 옵션이 있습니까? RAM 디스크를 구성한 다음 데이터를 저장하도록 테스트 데이터베이스를 구성 할 수 있어야합니다.하지만 Django / MySQL에 특정 데이터베이스에 대해 다른 데이터 디렉터리를 사용하도록 지시하는 방법을 잘 모르겠습니다. 특히 계속 지워지기 때문입니다. 각 실행을 재현했습니다. (저는 Mac FWIW를 사용하고 있습니다.)
답변
테스트를 실행할 때 데이터베이스 엔진을 sqlite3로 설정하면 Django는 메모리 내 데이터베이스를 사용합니다. .
settings.py
테스트를 실행할 때 엔진을 sqlite로 설정하기 위해 다음 과 같은 코드를 사용하고 있습니다 .
if 'test' in sys.argv:
DATABASE_ENGINE = 'sqlite3'
또는 Django 1.2에서 :
if 'test' in sys.argv:
DATABASES['default'] = {'ENGINE': 'sqlite3'}
마지막으로 Django 1.3 및 1.4에서 :
if 'test' in sys.argv:
DATABASES['default'] = {'ENGINE': 'django.db.backends.sqlite3'}
(백엔드에 대한 전체 경로는 Django 1.3에서 꼭 필요한 것은 아니지만 설정이 앞으로 호환되도록합니다.)
South 마이그레이션에 문제가있는 경우 다음 줄을 추가 할 수도 있습니다.
SOUTH_TESTS_MIGRATE = False
답변
나는 일반적으로 테스트를 위해 별도의 설정 파일을 만들고 테스트 명령에서 사용합니다.
python manage.py test --settings=mysite.test_settings myapp
두 가지 이점이 있습니다.
-
test
sys.argv에서 확인 하거나 그러한 마법의 단어 를 확인할 필요가 없습니다test_settings.py
.from settings import * # make tests faster SOUTH_TESTS_MIGRATE = False DATABASES['default'] = {'ENGINE': 'django.db.backends.sqlite3'}
또는 테스트 설정을 프로덕션 설정과 명확하게 분리하여 필요에 따라 추가로 조정할 수 있습니다.
-
또 다른 이점은 미묘한 버그를 피하는 sqlite3 대신 프로덕션 데이터베이스 엔진으로 테스트를 실행할 수 있다는 것입니다.
python manage.py test --settings=mysite.test_settings myapp
코드를 커밋하기 전에 한 번 실행
python manage.py test myapp
모든 테스트가 실제로 통과되었는지 확인합니다.
답변
MySQL은 데이터베이스 구성 ( settings.py
)에서 다음과 같이 구성 할 수있는 “MEMORY”라는 스토리지 엔진을 지원합니다 .
'USER': 'root', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'OPTIONS': {
"init_command": "SET storage_engine=MEMORY",
}
MEMORY 저장소 엔진은 blob / text 열을 지원하지 않으므로 django.db.models.TextField
이를 사용하는 경우 작동하지 않습니다.
답변
주요 질문에 답할 수는 없지만 작업 속도를 높이기 위해 할 수있는 몇 가지가 있습니다.
먼저 MySQL 데이터베이스가 InnoDB를 사용하도록 설정되어 있는지 확인하십시오. 그런 다음 트랜잭션을 사용하여 각 테스트 전에 db의 상태를 롤백 할 수 있는데, 내 경험상 엄청난 속도 향상을 가져 왔습니다. settings.py (Django 1.2 구문)에서 데이터베이스 init 명령을 전달할 수 있습니다.
DATABASES = {
'default': {
'ENGINE':'django.db.backends.mysql',
'HOST':'localhost',
'NAME':'mydb',
'USER':'whoever',
'PASSWORD':'whatever',
'OPTIONS':{"init_command": "SET storage_engine=INNODB" }
}
}
둘째, 매번 South 마이그레이션을 실행할 필요가 없습니다. 설정 SOUTH_TESTS_MIGRATE = False
당신의 settings.py에서 데이터베이스는 더 빨리 모든 역사적인 마이그레이션을 통해 실행하는 것보다 될 것입니다 일반 syncdb로 생성됩니다.
답변
이중 조정을 수행 할 수 있습니다.
- 트랜잭션 테이블 사용 : 초기 조명기 상태는 모든 TestCase 후 데이터베이스 롤백을 사용하여 설정됩니다.
- 데이터베이스 데이터 디렉토리를 ramdisk에 넣으십시오. 데이터베이스 생성에 관한 한 많은 것을 얻을 수 있으며 테스트를 실행하는 것이 더 빠를 것입니다.
나는 두 가지 트릭을 모두 사용하고 있으며 매우 행복합니다.
Ubuntu에서 MySQL 용으로 설정하는 방법 :
$ sudo service mysql stop
$ sudo cp -pRL /var/lib/mysql /dev/shm/mysql
$ vim /etc/mysql/my.cnf
# datadir = /dev/shm/mysql
$ sudo service mysql start
메모리에서 데이터베이스를 다시 부팅 한 후에는 테스트 용일뿐입니다.
답변
또 다른 접근 방식 : RAM 디스크를 사용하는 tempfs에서 MySQL의 다른 인스턴스를 실행하는 것입니다. 이 블로그 게시물의 지침 : Django 테스트를 위해 MySQL 속도 향상 .
장점 :
- 프로덕션 서버에서 사용하는 것과 똑같은 데이터베이스를 사용합니다.
- 기본 mysql 구성을 변경할 필요가 없습니다.
답변
Anurag의 답변을 확장하여 동일한 test_settings를 만들고 manage.py에 다음을 추가하여 프로세스를 단순화했습니다.
if len(sys.argv) > 1 and sys.argv[1] == "test":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.test_settings")
else:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
sys가 이미 가져오고 manage.py는 명령 줄을 통해서만 사용되므로 더 깔끔해 보입니다. 설정을 복잡하게 만들 필요가 없습니다.