11

たくさんの作業ユニットテストを書いたDjango(v1.4、Postgresqlを使用)プロジェクトがあります。これらはFactoryBoyを使用してほとんどのデータを生成します。

私は今、LiveServerTestCaseとSeleniumを使用していくつかの統合テストを書き始めています。テストとライブテストサーバーが異なるデータベースを使用していることに気づきました。つまり、私のテストで工場によって作成されたデータは、Seleniumでは利用できません。

進歩するための最良の方法がわかりません。フィクスチャを使用して機能するデータを提供できると思いますが、代わりにファクトリを使用することでこれまでのところ苦痛になっています。

工場を引き続き使用して、Seleniumテストで機能するデータを生成する方法はありますか?本当に、テストとLiveServerTestCaseで同じデータベースを使用したいと思います。

4

2 に答える 2

12

なぜこれが私に起こったのか、そして上記のIlyaBaryshevの答えを含むいくつかの可能な回避策を見つけました。

テストがDjangoの子孫TestCaseであり、データベースがトランザクションをサポートしている場合、各テストは独自のトランザクションで実行され、外部の誰も(他のスレッド、外部プロセス、または他のテスト)、テストによってデータベースに作成されたオブジェクトを見ることができません。

LiveServerTestCaseスレッドを使用するため、この問題が発生します。そのため、設計者は、変更がグローバルに表示されるように、これらのトランザクションを無効にするTransactionTestCaseのではなく、から継承するようにしました。TestCase

私に起こったことは、テストクラスにいくつかのミックスインを追加し、そのうちの1つをプルインしたことTestCaseです。これによってエラーが発生することはありませんが、の基本クラスがにサイレントに置き換えLiveServerTestCaseられTestCase、トランザクションが再び有効になり、説明した問題が発生します。

IlyaのSQLiteメモリデータベースの回避策は:memory:、スレッド間で実際に同じ接続を共有するSQLiteデータベースを使用するときに検出するコードがDjangoに含まれているために機能します。したがって、テストのオブジェクトは同じトランザクションLiveServerThread内にあるため、に表示されます。ただし、これにはいくつかの注意点があります。

2つのスレッドによるこの共有接続を介したデータベースクエリの同時発生を防ぐことが重要です。これにより、テストがランダムに失敗する場合があります。したがって、2つのスレッドが同時にデータベースにアクセスしないようにする必要があります。特に、これは、場合によっては(たとえば、リンクをクリックした後やフォームを送信した直後)、Seleniumが応答を受信し、次のページが読み込まれたことを確認してから、さらにテストを実行する必要があることを意味します。これを行うには、たとえば、応答でHTMLタグが見つかるまでSeleniumを待機させます(Selenium> 2.13が必要です)...

https://docs.djangoproject.com/en/1.4/topics/testing/#live-test-server

私の場合、autocommitテストの開始時にオフになっていた識別子を特定し、その理由を突き止めたら(TestCase実行すべきでないコードを入力したため)、継承階層を修正して、プルインを回避することができましたTestCase。次に、ライブサーバースレッドとテストの両方から同じデータベースが表示されました。

これはPostgresデータベースでも機能するため、velotronのソリューションを提供します。

于 2014-08-01T13:49:58.290 に答える
6

テスト用のデータベースバックエンドとしてsqliteを使用してみましたか?

インメモリSQLiteデータベースを使用してテストを実行する場合、同じデータベース接続が2つのスレッド(ライブサーバーが実行されるスレッドとテストケースが実行されるスレッド)によって並行して共有されます。

Djangoドキュメントから

通常のORM以外のものを使用していない場合は、テストの高速化も役立つ可能性があります。

于 2012-11-10T14:38:28.610 に答える