在django下很容易写测试,只需要继承DjangoTestCase,它会自动创建一个测试数据库,每次运行时加载必要的fixture数据,以保证每个测试的初始状态是一致、可预测的。其前提是必须使用它的dbmodel,如果使用MySQL, Oracle等关系型数据库,这自然不是个问题。如果使用其它数据库,例如当前相当流行的NoSQL,这时DjangoTestCase就不能直接拿来用了。如果我们hack一下django,也是可以使用DjangoTestCase的。以mongodb为例,我使用的是django1.2,1.2以下的版本不能用这里的方式,我没有研究过,但我相信也是能hack的。
django有TestRunner,用来启动测试,加载fixture的工作就是在这里做的。默认的TestRunner是'django.test.simple.DjangoTestSuiteRunner',而它加载fixture的实际上调用的是loaddata命令。所以要实现fixture的加载工作,最简单的方式就是重新定义loaddata命令,让它将数据加载到mongodb中。随便选择一个app,在它的下面创建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': 'xxxxx' }来表示,这就需要做某种转换,这是在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" : "marlon@163.com",
"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...' ]
另外还需要在运行时创建测试数据库,在测试运行完成之后drop掉数据库。实现起来也很容易,只需要覆盖DjangoTestSuiteRunner的setup_databases和teardown_databases方法就可以了。
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为MongoTestSuiteRunner:
TEST_RUNNER = 'project.utils.test.SATestSuiteRunner'
完成这些工作之后就可以直接使用DjangoTestCase来写单元测试了,我就不教怎么写了。
分享到:
相关推荐
在Django中使用MongoDB,通常需要借助如`django-mongodb-engine`或`django-pymongo`这样的第三方库,它们提供了与Django ORM的接口,使得开发者能像操作传统关系数据库一样操作MongoDB。 3. CMS内容管理系统:内容...
基于Django框架和mongodb的Web寻宝游戏源码+实验报告+测试视频.zip基于Django框架和mongodb的Web寻宝游戏源码+实验报告+测试视频.zip基于Django框架和mongodb的Web寻宝游戏源码+实验报告+测试视频.zip基于Django框架...
多纳·维达 使用Django Rest Framework和MongoDB进行的献血者后端项目。入门这些说明将为您提供在本地计算机上运行并运行的项目的副本,以进行开发和测试。先决条件如果您想尝试,则需要具备以下先决条件Python > ...
`django-mongom2m` 是一个专门针对 Django 框架与 MongoDB 数据库结合使用的扩展库,它提供了对 MongoDB 中特有的 ManyToManyField(多对多关系)的支持。在 Django 中,原生的 ORM(对象关系映射)系统主要设计用于...
高分毕业设计 基于Python爬虫+Django+MongoDB的豆瓣数据可视化分析系统源码+部署文档+全部数据资料.zip高分毕业设计 基于Python爬虫+Django+MongoDB的豆瓣数据可视化分析系统源码+部署文档+全部数据资料.zip高分毕业...
基于node.js、vue、mongodb等技术构建的web系统,界面美观,功能齐全,适合用作毕业设计、课程设计作业等,项目均经过测试,可快速部署运行! 基于node.js、vue、mongodb等技术构建的web系统,界面美观,功能齐全,...
基于node.js、vue、mongodb等技术构建的web系统,界面美观,功能齐全,适合用作毕业设计、课程设计作业等,项目均经过测试,可快速部署运行! 基于node.js、vue、mongodb等技术构建的web系统,界面美观,功能齐全,...
Python毕业设计 基于Django+Scrapy+MongoDB的小说搜索引擎系统的设计与实现+详细文档+全部资料.zipPython毕业设计 基于Django+Scrapy+MongoDB的小说搜索引擎系统的设计与实现+详细文档+全部资料.zip 【备注】 1、该...
利用 MongoDB 的主从 or 主主复制 django直接部署到派上(尝试服务器环境生成 Docker,然后部署到派上,直接部署 Django 可能会出现兼容性问题) 添加可写卡片 data 数据的功能 -------- <项目介绍> 该资源内项目...
python毕业设计-基于Django+ECharts+MongoDB的Web日志分析可视化系统设计与实现+使用说明.zippython毕业设计-基于Django+ECharts+MongoDB的Web日志分析可视化系统设计与实现+使用说明.zip 【备注】 1、该资源内项目...
【资源说明】 1、该资源内项目代码都是经过测试运行成功,功能正常的情况下才上传的,请放心下载使用。...基于树莓派的门禁管理系统源码+项目说明(技术点:树莓派、RFID、Django、Flask、MongoDB)(python).zip
基于Django的Web日志分析可视化系统python+css源码(ECharts+MongoDB).zip 基于Django的Web日志分析可视化系统python+css源码(ECharts+MongoDB).zip 基于Django的Web日志分析可视化系统python+css源码(ECharts+...
Django与MongoDB(Django and MongoDB)** 结合流行的Python Web框架Django与MongoDB,可以构建高性能的Web应用。这部分内容详细介绍了如何在Django项目中配置和使用MongoDB。 ### **6. 入门指南(Getting Started...
3)卖家用户接口,如创建店铺、填加书籍信息及描述、增加库存 通过对应的功能测试,所有 test case 都 pass 测试下单及付款两个接口的性能,测出支持的每分钟交易数,延迟等 4)实现后续的流程 发货 -> 收货 5)搜索...
经测试可运行。 详细介绍了一些Python框架的各种功能和模块,以及如何使用Python进行GUI开发、网络编程和跨平台应用开发等。 适用于初学者和有经验的开发者,能够帮助你快速上手JPython并掌握其高级特性。
Pyecharts使得在Python环境中创建复杂的图表变得简单,它可以轻松地与Django或其他Web框架集成,用于展示数据分析结果。 3. MySQL:MySQL是一款流行的开源关系型数据库管理系统,广泛应用于Web应用程序。在这个项目...
10. 测试与部署: 项目可能包含了单元测试、集成测试和端到端测试,确保系统的稳定性和正确性。部署可能选择云服务,如AWS或Google Cloud,也可能使用Docker容器化技术进行部署,以保证环境的一致性。 总的来说,这...
7. 测试与优化:系统开发完成后,需要进行功能测试、性能测试以及A/B测试,确保推荐的准确性和系统稳定性。同时,通过对用户反馈和系统数据的分析,不断优化推荐算法和系统设计,提升用户体验。 总的来说,这个毕业...