django,mongodb 및 테스트
django 에서 테스트 를 쉽게 쓸 수 있 습 니 다.Django TestCase 를 계승 하면 테스트 데이터 베 이 스 를 자동 으로 만 들 고 실행 할 때마다 필요 한 fixture 데 이 터 를 불 러 와 서 모든 테스트 의 초기 상태 가 일치 하고 예측 가능 하도록 합 니 다.그 전 제 는 dbmodel 을 사용 해 야 한 다 는 것 이다.MySQL,Oracle 등 관계 형 데이터 베 이 스 를 사용 하면 문제 가 되 지 않 는 다.현재 상당히 유행 하 는 NoSQL 과 같은 다른 데이터 베 이 스 를 사용 하면 Django TestCase 를 직접 사용 할 수 없습니다.만약 우리 가 django 를 hack 한다 면,Django TestCase 를 사용 할 수도 있 습 니 다.mongodb 의 경우 저 는 django 1.2,1.2 이하 의 버 전 을 사용 할 수 없습니다.저 는 연구 한 적 이 없 지만 hack 도 할 수 있다 고 믿 습 니 다.
django 는 TestRunner 가 있 습 니 다.테스트 를 시작 할 때 fixture 를 불 러 오 는 작업 은 여기 서 합 니 다.기본 TestRunner 는'django.test.simple.Django Test SuiteRunner'이 며,fixture 를 불 러 오 는 실제 호출 은 loaddata 명령 입 니 다.따라서 fixture 의 로드 작업 을 실현 하려 면 가장 간단 한 방법 은 loaddata 명령 을 다시 정의 하여 데 이 터 를 mongodb 에 불 러 오 는 것 입 니 다.아무 앱 이나 선택 하여 아래 에 management 디 렉 터 리 를 만 들 고 management 아래 commands 디 렉 터 리 를 만 든 다음 에 loaddata.py 를 만 듭 니 다.디 렉 터 리 마다 를 만들어 야 합 니 다.init__.py 파일.명령 을 만 드 는 작업 은 여 기 를 참고 할 수 있 습 니 다.일반 fixture 의 형식 은 json 형식 을 사용 할 수도 있 고 xml 로 쓸 수도 있 으 며 일반 텍스트 형식 을 사용 할 수도 있 지만 해석 하기 가 복잡 하고 유연성 이 부족 하기 때문에 json 을 사용 하 는 것 을 추천 합 니 다.loaddata.py 는 대략 다음 과 같 습 니 다.
from optparse import make_option
from django.core.management.base import BaseCommand
from django.db.models import get_apps
from django.utils import simplejson as json
from pymongo.objectid import ObjectId
class Command(BaseCommand):
help = 'Installs the named fixture(s) in the database.'
args = "fixture [fixture ...]"
option_list = BaseCommand.option_list + (
make_option('--database', action='store', dest='database',
default='default db', help='Nominates a specific database to load '
'fixtures into. Defaults to the "default" database.'),
)
def handle(self, *fixture_labels, **options):
app_fixtures = [os.path.join(os.path.dirname(app.__file__), 'fixtures') for app in get_apps()]
for fixture_label in fixture_labels:
for fixture_dir in app_fixtures:
fullpath = os.path.join(fixture_dir, fixture_label)
if os.path.isfile(fullpath):
fixture = open(fullpath, 'r')
data = norm_object(json.loads(fixture.read()))
self._do_load(data)
json 은 몇 가지 int,string,bool,array,dict 의 몇 가지 데이터 형식 만 있 기 때문에 datetime,ObjectId(이것 은 mongodb 에서 ID 가 기본적으로 사용 하 는 유형)등 복잡 한 유형 을 대표 하려 면 datetime 에 대해 서 는{'$date':'2009/8/3 05:07:23'}을 사용 할 수 있 고 ObjectId 에 대해 서 는{'$oid':'xxxx'}를 사용 하여 표시 할 수 있 습 니 다.이것 은 어떤 전환 이 필요 합 니 다.이것 은 norm 입 니 다.object 에서 완 성 된 것:
def norm_object(data):
if isinstance(data, dict):
if data.has_key('$oid'): # ObjectId
return ObjectId(data[u'$oid'])
if data.has_key('$date'): # datetime
return parse_datetime(data['$date'])
if data.has_key('$ref'): #dbref
from pymongo.dbref import DBRef
return DBRef(data['$ref'], ObjectId(data['$id']))
if isinstance(data, dict):
return dict( [ (norm_object(k), norm_object(v)) for k, v in data.iteritems() ])
if isinstance(data, list):
return [ norm_object(o) for o in data ]
return data
대do_load 방법 은 fixture 의 데 이 터 를 mongodb 에 불 러 오 는 것 입 니 다.할 말 이 없습니다.유일 하 게 설명 해 야 할 것 은 데 이 터 를 어느 collection 에 불 러 올 지 지정 하면 저 는 fixture 의 모든 데이터 에서 데이터 베 이 스 를 불 러 올 부분 을 제외 하고 도 추가 합 니 다.collection 속성,어떤 collection 에 불 러 올 지 표시 합 니 다.사용자 데이터 의 fixture 가 이 럴 수 있 습 니 다:
[
{
"_collection": "user",
"_id" : { "$oid", "000011112222333344440001" },
"username" : "marlon",
"email" : "[email protected]",
"password" : "sha1$6f90a$a1d2d0526aec9338e2d5ab7406315df849d9efdf",
"is_active" : true
}
]
_do_load 방법 은 다음 과 같 습 니 다.
def _do_load(self, data):
db = get_db()
for obj in data:
col = obj.pop('_collection')
col = getattr(db, col)
col.save(obj, save=True)
여기까지 fixture 로 딩 부분 을 실 현 했 습 니 다.테스트 를 실행 하기 전에 fixture 를 불 러 오고 app 디 렉 터 리 에 fixtures 디 렉 터 리 를 만 든 다음 에 해당 하 는 fixture 를 만 듭 니 다.예 를 들 어 users.json.TestCase 에서 fixtures 데 이 터 는 fixture 의 파일 이름 을 가리 키 고 있 습 니 다:
class UserTestCase(DjangoTestCase):
fixtures = [ 'users.json', 'other fixture...' ]
또한 실행 할 때 테스트 데이터 베 이 스 를 만 들 고 테스트 실행 이 끝 난 후에 데이터 베 이 스 를 드 롭 해 야 합 니 다.실현 도 쉬 워 요.Django Test Suite Runner 를 덮어 쓰 는 setupdatabases 와 teardowndatabases 방법 이면 됩 니 다.
class MongoTestSuiteRunner(DjangoTestSuiteRunner):
def setup_databases(self, **kwargs):
self._test_dbname = 'test_' + settings.MONGODB_NAME
settings.MONGODB_NAME = self._test_dbname
# do some database intialize work here
# ...
return super(MongoTestSuiteRunner, self).setup_databases(**kwargs)
def teardown_databases(self, old_config, **kwargs):
conn = get connection ...
print 'drop mongo database %s...' % self._test_dbname
conn.drop_database(self._test_dbname)
super(MongoTestSuiteRunner, self).teardown_databases(old_config, **kwargs)
마지막 으로 settings.py 에서 testrunner 를 MongoTest SuiteRunner 로 지정 해 야 합 니 다.
TEST_RUNNER = 'project.utils.test.SATestSuiteRunner'
이 작업 을 마 친 후에 Django TestCase 를 사용 하여 유닛 테스트 를 쓸 수 있 습 니 다.저 는 어떻게 쓰 는 지 가르쳐 주지 않 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Django 라우팅 계층 URLconf 작용 및 원리 해석URL 구성(URLconf)은 Django가 지원하는 웹 사이트의 디렉토리와 같습니다.그것의 본질은 URL과 이 URL을 호출할 보기 함수 사이의 맵표입니다. 위의 예제에서는 URL의 값을 캡처하고 위치 매개 변수로...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.