Python 在内存中运行Django MySQL测试

Python 在内存中运行Django MySQL测试,python,mysql,django,Python,Mysql,Django,我有一个django 1.4项目,使用mysql作为后端。我已将测试设置为在内存中运行 if 'test' in sys.argv: DATABASES['default'] = {'ENGINE': 'django.db.backends.sqlite3'} 问题是我需要使用mysql功能(全文索引) 有没有办法让django在内存中运行MySQL进行测试? 我的项目依赖于全文索引。在I syncdb上开发项目时,使用sql执行.sql文件以创建全文索引 我想在我测试的函数中使用djan

我有一个django 1.4项目,使用mysql作为后端。我已将测试设置为在内存中运行

if 'test' in sys.argv:
  DATABASES['default'] = {'ENGINE': 'django.db.backends.sqlite3'}
问题是我需要使用mysql功能(全文索引)

有没有办法让django在内存中运行MySQL进行测试?

我的项目依赖于全文索引。在I syncdb上开发项目时,使用sql执行
.sql
文件以创建全文索引

我想在我测试的函数中使用django orm全文搜索。我尝试在每个测试的初始化上手动添加全文索引,如:

cursor.execute('altertablemytableaddfulltext(一,二)')

这在使用sqlite时不起作用(我认为是因为sqlite不支持全文索引)

当我删除内存中的测试时,上面的sql确实起作用。我喜欢记忆测试的速度有没有办法在内存中运行mysql?

人们如何测试依赖数据库特定功能的应用程序?如全文索引或地理信息系统等。。。他们必须在文件系统上正常运行测试吗


谢谢你

MySQL有一个
内存
存储引擎。您可以使用
选项
键激活它:

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'
            }
        }
    }
但是根据:

因此,我认为它对于您(和许多其他)用例来说是非常无用的


我在中找到了一些加速MySQL测试的其他技巧。请务必阅读Daniel Roseman关于使用INNODB引擎的回答。

不要测试MySQL。MySQL已经过开发人员的测试。
您的工作是以这种方式编码,这样您就可以用一个模拟Python对象代替MySQL连接,该对象将返回MySQL将返回的任何内容(或者如果发送到MySQL的查询是您想要的,则断言)

,正如monkut在问题注释中建议的那样,通过将测试数据库存储在RAM驱动器上,您可以获得一些MySql加速。例如在Linux上运行的tmpfs文件系统。然而,如果您担心测试期间的速度,这可能不会提供太多的速度改进,因为MySql通常会将其数据缓存在内存中

我使用的方法是编写一个测试装饰器,它将跳过给定数据库后端不支持的测试,然后使用不同的
settings.py
文件对不同的后端进行测试

在这里,我使用了一些功能来帮助编写一个装饰程序,以便在任何测试数据库使用SQLite时跳过测试

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
然后,使用不同的
数据库设置设置设置
设置.test.mysql
设置.test.sqlite
。如果使用
settings.test.sqlite
执行测试,则将跳过依赖MySql特定功能的测试,但如果针对
settings.test.MySql
运行测试,则将执行测试


这种方法允许您专门针对特定数据库后端的测试,但仍然提供了在开发过程中针对更快的SQLite数据库运行大多数测试的灵活性。

mysql支持表空间吗?在linux上,您可以将dbs表空间设置为放置在RAM磁盘上。这里唯一的问题是,访问DB的方法可能有很多种,而对它们进行模拟会耗费大量时间,而模拟太少会限制实现。理想情况下,测试应该是关于意图而不是实现的。这通常是一个很好的建议。。。在编写“你好,世界”风格的程序时。任何与数据库对话的非琐碎内容都取决于该数据库的行为,因此必须对整个数据库进行测试,否则您很快就会发现所讨论的数据库所做的事情与您的模拟数据库所做的事情并不完全相同。@ayanami:在生产中使用的存储引擎之外的不同存储引擎上进行测试也是一样的。MySQL的内存引擎在某些情况下的行为与MyISAM和InnoDB不同。一旦我们谈到集成测试(在本文中我们似乎是这样),它们应该在目标配置上运行。这意味着这些测试有时会很慢。
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