4

我正在使用 py2exe 和 Qt 实现 Django。有一个使用 South 管理的 SQLite 数据库。

使用内存数据库在源代码上运行 django 测试很好,但我也在尝试使用 PhantomCSS (PhantomJS) 实现测试以执行 CSS 回归测试。

为此,我有一个LiveServerTestCase( source ) 的子类。我正在使用磁盘上的 sqlite 数据库运行 Django 测试,在启动自定义服务器进程时通过调用 loaddata 加载固定装置(请参阅最后的服务器函数)。

它的测试看起来像这样;

class PhantomTestBackupRestore(PhantomTestCase):

    fixtures = ['basic_db.json',]

    def test_backup(self):
        self.assertTrue(
            self.phantom(RUNNER_PATH,
                screenID='lupyvAQL',
                host='http://127.0.0.1',
                port=buildconstants.PRODUCT_LISTENPORT)
        )

我正在使用以下命令创建的夹具(昨天加载的,所以似乎是一个气质问题loaddata);

manage.py dumpdata -n --indent 4 --exclude=contenttypes --exclude=auth --format=json > phantom/fixtures/basic_db.json

我得到以下堆栈跟踪;

 [exec] Traceback (most recent call last):
 [exec]   File "C:\Python27\lib\multiprocessing\process.py", line 258, in _bootstrap
 [exec]     self.run()
 [exec]   File "C:\Python27\lib\multiprocessing\process.py", line 114, in run
 [exec]     self._target(*self._args, **self._kwargs)
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django_offline\startuphelpers.py", line 124, in django_server_helper
 [exec]     *fixture_list
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\core\management\base.py", line 283, in execute
 [exec]     output = self.handle(*args, **options)
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\core\management\commands\loaddata.py", line 55, in handle
 [exec]     self.loaddata(fixture_labels)
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\core\management\commands\loaddata.py", line 84, in loaddata
 [exec]     self.load_label(fixture_label)
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\core\management\commands\loaddata.py", line 140, in load_label
 [exec]     obj.save(using=self.using)
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\core\serializers\base.py", line 164, in save
 [exec]     models.Model.save_base(self.object, using=using, raw=True)
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\db\models\base.py", line 578, in save_base
 [exec]     updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\db\models\base.py", line 638, in _save_table
 [exec]     updated = self._do_update(base_qs, using, pk_val, values, update_fields)
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\db\models\base.py", line 676, in _do_update
 [exec]     return base_qs.filter(pk=pk_val)._update(values) > 0
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\db\models\query.py", line 509, in _update
 [exec]     return query.get_compiler(self.db).execute_sql(None)
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\db\models\sql\compiler.py", line 971, in execute_sql
 [exec]     cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)

 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\db\models\sql\compiler.py", line 777, in execute_sql
 [exec]     cursor.execute(sql, params)
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\db\utils.py", line 105, in inner
 [exec]     return func(*args, **kwargs)
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\db\utils.py", line 99, in __exit__
 [exec]     six.reraise(dj_exc_type, dj_exc_value, traceback)
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\db\utils.py", line 105, in inner
 [exec]     return func(*args, **kwargs)
 [exec]   File "C:\Users\markw\work\bptrti3b\src\django\db\backends\sqlite3\base.py", line 445, in execute
 [exec]     return Database.Cursor.execute(self, query, params)
 [exec] OperationalError: Problem installing fixture 'C:\Users\markw\work\src\phantom\fixtures\basic_db.json': 
Could not load sites.Site(pk=1): no such table: django_site

因为我正在处理多处理,所以当这些错误发生时,我不确定 manage.py 是否正在使用内存数据库或其他东西,但是对于以下数据库设置,我认为它没有使用内存进行测试;

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(
            APPDATA_DIR, 'sqlite3.db',
        ),
        'TEST_NAME': os.path.join(
            APPDATA_DIR, 'test.db',
        )
    }
}

启动服务器的功能(如果有帮助);

def django_server_helper(qt_pipe=None, fixture_list=None):
    """    
    This is for use in testing-only modes (e.g. PhantomCSS).

    If this process is a subprocess of the main application, qt_pipe will be
    supplied to allow us to access functionality provided by django_offline.
    The other end of this pipe comes out in the DjangoOfflineApp instance.

    @type qt_pipe: multiprocessing.Connection
    @param qt_pipe: Pipe for communicating with the main django_offline app.
    @type fixture_list: list or None
    @param fixture_list: List of JSON fixture files to load in for testing.

    @rtype: None
    """
    use_threading = True

    if fixture_list is not None:
        # A fixture list has been supplied, so we're in test mode.
        from django.core.management.commands import loaddata
        loaddata.Command().execute(
            verbosity = 0,
            database = "default",
            settings = "mysite.settings",
            *fixture_list
        )

    if qt_pipe is not None:
        # A pipe has been supplied, so we're a subprocess
        from django_offline import connector
        connector.QT_PIPE = qt_pipe

    # start the django server up
    from django_offline import settings_central
    try:
        from django.contrib.staticfiles.management.commands import runserver
        runserver.Command().execute(
            use_threading=use_threading,
            use_static_handler=True,
            insecure_serving=True,
            addrport='127.0.0.1:{0}'.format(settings_central.LISTEN_PORT),
        )
    except socket.error as e:
        logging.exception("Socket occupied; not starting a server.")
        sys.exit(1)
    sys.exit(0)

我是否需要syncdb在跑步前打电话,loaddata或者这可以通过使用夹具列表向 South 进行迁移调用来完成?

4

1 回答 1

1

问题是代码loaddata在数据库表设置之前运行,因此无法写入Site值。

通常manage.py test负责设置测试数据库 - 您是否使用不同的/自定义测试运行器运行?如果不是,请尝试逐步manage.py test查看测试代码的初始化顺序与调用的顺序syncdb

如果您使用自己的测试运行程序,则添加适当的调用syncdb. 如果使用 South,请确保选择 South 版本,和/或设置SOUTH_TESTS_MIGRATE = False

于 2013-09-25T09:48:04.560 回答