我有一个使用mysql作为后端的django 1.4项目。我将测试设置为在内存中运行
if 'test' in sys.argv:
DATABASES['default'] = {'ENGINE': 'django.db.backends.sqlite3'}
问题是我需要使用mysql功能(全文索引)。
有没有办法让django在内存中运行MySQL进行测试?
我的项目依赖于全文索引。当我在syncdb上开发项目时,然后用sql执行.sql
文件来创建全文索引。
我想在我测试的函数中使用django orm全文搜索。我试图在每个测试的初始化上手动添加全文索引,如:
cursor.execute('alter table mytable add fulltext(one, two)')
使用sqlite时这不起作用(我相信因为sqlite不支持全文索引)
当我删除内存测试时,上面的sql DOES工作。我喜欢内存测试的速度。 有没有办法在内存中运行mysql?
人们如何测试依赖于数据库特定功能的应用?像全文索引或gis等...他们是否必须在文件系统上正常运行测试?
谢谢
答案 0 :(得分:14)
MySQL有一个MEMORY
存储引擎。您可以使用OPTIONS
键激活它:
if 'test' in sys.argv:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': 'localhost',
'NAME': 'foo',
'USER': 'bar',
'PASSWORD': 'baz',
'OPTIONS': {
'init_command': 'SET storage_engine=MEMORY'
}
}
}
但根据documentation:
MEMORY tables cannot contain BLOB or TEXT columns.
因此,我认为这对您(以及许多其他)用例来说毫无用处。
我在this thread中找到了一些加速MySQL测试的其他技巧。请务必阅读Daniel Roseman关于使用INNODB
引擎的答案。
答案 1 :(得分:3)
正如monkut在问题评论中建议的那样,您可以通过将测试数据库存储在RAM驱动器上来获得一些MySql加速。例如,如果在Linux上运行,则为tmpfs文件系统。但是,如果你担心测试期间的速度,这可能无法提高速度,因为MySql通常会将其数据缓存在内存中。
我使用的方法是编写一个测试装饰器,它将跳过给定数据库后端不支持的测试,然后使用不同的settings.py
文件来测试不同的后端。
在这里,如果任何测试数据库使用SQLite,我使用django-nose功能来帮助编写装饰器以跳过测试。
from nose import SkipTest
from django.conf import settings
def skip_if_sqlite(test_fn):
"""Nose test decorator to skip test if testing using sqlite databases.
This may be useful when we know that a test will fail when using sqlite,
possibly because the test uses functionality not supported on sqlite such
as database views or full text indexes.
This decorator can be used as follows:
@skip_if_sqlite
def my_test_that_shouldnt_run_if_sqlite_database(self):
pass
"""
@functools.wraps(test_fn)
def wrapper(*args, **kwargs):
# Skip test if any database contain a sqlite engine.
for alias, db_settings in settings.DATABASES.iteritems():
if 'sqlite' in db_settings['ENGINE']:
raise SkipTest()
return test_fn(*args, **kwargs)
return wrapper
然后,使用不同的settings.test.mysql
设置设置settings.test.sqlite
和DATABASE
。如果使用settings.test.sqlite
执行测试,将跳过依赖于MySql特定功能的测试,但如果您正在针对settings.test.mysql
运行测试,则测试将执行。
这种方法允许您专门针对特定数据库后端的测试,但仍然可以灵活地在开发过程中针对速度更快的SQLite数据库运行大多数测试。
答案 2 :(得分:-3)
不要测试MySQL。 MySQL已经过其开发人员的测试。 你的工作就是以这种方式编写代码,这样你就可以用一个模拟的Python对象代替MySQL连接,这个对象将返回MySQL将返回的内容(或者断言,如果发送给MySQL的查询是你想要的那样)