4

私はpy2exeとQtを使用してDjangoの実装に取り​​組んでいます。South を使用して管理される SQLite db があります。

ソースで django テストを実行することはメモリ データベースで問題ありませんが、CSS 回帰テストを実行するために PhantomCSS (PhantomJS) を使用してテストを実装しようとしています。

これを行うために、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 に答える