1

Djangoのテストスイートで奇妙な問題が発生しているので、それを修正する方法や、少なくともどこを見ればよいかについての洞察を探しています。

テディベアーズアプリをテストするために以下を実行すると、次のようになります。

python manage.py test teddybears

このエラーが発生します:

...django/db/backends/sqlite3/base.py", line 344, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.DatabaseError: table "teddybears_teddybear" already exists

名前の衝突を避けるために、デフォルトでDBの前に「test」という単語を付けるべきではありませんか?これを回避するために、DBの名前を「:memory:」に変更しましたが、それでも同じエラーが発生します。

開発は正常に機能し、すべてが期待どおりに機能しています。テストスイートを機能させることができません。何がこれを引き起こしているのか、どこを見ればよいのかについての洞察をいただければ幸いです。

ローカル開発作業にSQLiteを使用し、Django1.4.3を使用しています

完全なスタックトレースは次のとおりです。

> python manage.py test teadybears
Creating test database for alias 'default'...
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 443, in execute_from_command_line
    utility.execute()
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 382, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/commands/test.py", line 49, in run_from_argv
    super(Command, self).run_from_argv(argv)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/base.py", line 196, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/base.py", line 232, in execute
    output = self.handle(*args, **options)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/commands/test.py", line 72, in handle
    failures = test_runner.run_tests(test_labels)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/test/simple.py", line 381, in run_tests
    old_config = self.setup_databases()
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/test/simple.py", line 317, in setup_databases
    self.verbosity, autoclobber=not self.interactive)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/db/backends/creation.py", line 271, in create_test_db
    load_initial_data=False)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 150, in call_command
    return klass.execute(*args, **defaults)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/base.py", line 232, in execute
    output = self.handle(*args, **options)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/base.py", line 371, in handle
    return self.handle_noargs(**options)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/core/management/commands/syncdb.py", line 102, in handle_noargs
    cursor.execute(statement)
  File "/Work/projects/teadybears/venv/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 344, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.DatabaseError: table "teadybears_teadybear" already exists

返事:

これが私のDB設定です:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'database.sqlite',                      # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

私はそこにこれを持っていましたが、違いはありませんでした:

if 'test' in sys.argv:
    DATABASES['default']['NAME'] = ':memory:'

2 XGrrr...。

残念ながら、問題は修正されていません。DB名を変更する以外は、提案されたすべてを試しましたが、それでも修正されませんでした。

私は以下を含むすべての提案をしました:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'database.sqlite',                      # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
        'TEST_NAME': 'mud',
    }
}

それは今私に尋ねます:

python manage.py test teddybears
Creating test database for alias 'default'...
Destroying old test database 'default'...
Type 'yes' if you would like to try deleting the test database 'mud', or 'no' to cancel:

それでも同じエラーが発生します。

これを修正するためだけに別のクリーンなプロジェクトに移動するのは嫌だと思いますが、それでも面倒です。


何が私をつまずかせているのか理解しました。プロジェクトのモデルの1つに、テストが失敗する原因となったメタクラスに設定された値がありました。

class TeddybearExtra(Teddybear):

    class Meta:
        db_table = 'teddybears_teddybear'

ご覧のとおり、これは元のモデルのサブクラスであり、「db_table」属性が明示的に設定されているため、自動生成されたテーブル名が上書きされます。ここで学んだ教訓は、メタオブジェクトにdb_table属性を設定すると、テストツールで悪いことが起こるということです。どうしてもこの方法で処理する必要がある場合にのみ、これを実行してください。

4

2 に答える 2

4

ドキュメントには、発生している問題に関連する可能性のあるセクションが 2 つあります。

https://docs.djangoproject.com/en/dev/topics/testing/overview/#the-test-database

デフォルトでは、テスト データベースは、DATABASES で定義されたデータベースの NAME 設定の値に test_ を追加することによって名前を取得します。SQLite データベース エンジンを使用する場合、テストはデフォルトでインメモリ データベースを使用します (つまり、データベースはファイルシステムを完全にバイパスしてメモリ内に作成されます!)。別のデータベース名を使用する場合は、DATABASES の特定のデータベースのディクショナリで TEST_NAME を指定します。

と..

テストがモデルの作成やクエリなどのデータベース アクセスに依存している場合は、テスト クラスを unittest.TestCase ではなく django.test.TestCase のサブクラスとして作成してください。

上記の例では、いくつかのモデルをインスタンス化しますが、データベースには保存しません。unittest.TestCase を使用すると、トランザクションで各テストを実行してデータベースをフラッシュするコストを回避できますが、ほとんどのアプリケーションでは、この方法で記述できるテストの範囲はかなり制限されるため、django.test.TestCase を使用するのが最も簡単です。 .

まず、テストが からサブクラス化されていることを確認してくださいdjango.test.TestCase。次に、に設定TEST_NAMEしてみtestdb.sqliteて、問題が解決するかどうかを確認してください。のようにデータベースへのパスを指定することもできます/Work/database.sqlite。そうしないと、(私が思うに)実行元のディレクトリにデータベースが作成され、manage.pyそれが常に必要なものであるとは限りません。

settings最後に、テスト用の正しいファイルをロードしていることを確認してください。

于 2013-02-25T01:24:31.173 に答える
2

適切な設定モジュールを指していますか?試す:

python manage.py test teddybears --settings=myproject.settings.test
于 2013-02-24T22:43:36.543 に答える