2016-12-27 5 views
0

私はDjango(1.8)+ DRF + uwsgi + nginxを使用しており、私が作った単体テストAPIを試しています。テストを実行するには、dbにデータを入れる(たとえば、ユーザーを作成する)必要があり、すべてのテストでこのデータを使用する必要があります。だから私は、次の2つの方法を試してみた:djangoのビルトインテストツール用のdbデータの設定

はTestCase.setUpで直接作成します。

class ApiTests(TestCase): 
    def setUp(self): 
     Account.objects.create_user(username='username', password='password') 

または備品を使用します。

class ApiTests(TestCase): 
    fixtures = ['dump.json'] 

次の私は上司を通じて私のプロジェクトを実行します。

system("service supervisord startall") 

すべての準備ができたら、私はテストのために私のAPIにアクセスしてログインします:

login_data = {"username": "username", "password": "password"} 
rslt = client.post(HOST_NAME + '/login/', data=login_data) 

...しかし、ユーザーが何らかの形でdbに存在しないため、私は認証できません!

Djangoテストのドキュメントで見つけたように、TestCaseはdbにデータを書き込むのではなく、テスト後にロールバックしてトランザクションに格納します。私が見ることができるように、このデータはテスト側(User.objects.all()を使ってユーザが作成されていることを示している)で取得できますが、nginx-server側(User.objects.allこの側に0項目を示しています)。

  1. どういうわけか、DBにデータをコミットするのTestCaseを強制:私はいくつかのオプションを見ることができます

    ATM。

  2. 他の方法でデータを入力します(ただし、?)。
  3. 異なるテストライブラリを使用してください。

助けてください。

+2

なぜテストのコンテキスト外でテストデータにアクセスしたいのですか? –

+0

また、 'test-side'と' nginx-server-side'の意味を理解していませんか? –

+0

@ShangWang、setUp()中にテストを実行するために、私は2つのことを行います.dbにデータを入力し、私のWebサーバーのために私のロールアウトスクリプトを実行します。実際には、私は2つのPythonプログラムを実行しています.1つは、 "manage.py test myapp"(いわゆるテスト側)とテストしたいWebサーバです。 "サービススーパーバイザstartall "(いわゆるnginx - サーバー側)。私のテスト側はサーバー側にのみHTTP要求を送信するので、サーバー側はテストのコンテキストから分離されます。 – Fian

答えて

1

はい!あなたはすでに問題を特定しました。 Django TestCaseは、独自の小さな絶縁環境で実行されます。各スイートの実行開始時にtest_のプレフィックスが付いたテストデータベースを作成し、トランザクション内で各テストを実行するので、テストスイートを起動しても、初期化後に一時停止し、supervisordが指すdjangoの設定をテストデータベースを実行してもテストは続行されますが、まだデータは表示されません。

上記の例でデータが表示されない理由は、テストに独自のトランザクションがあるため、Webサーバーにリクエストを行うと、Webサーバーが別のトランザクションを開き、表示できなくなるためですテストのコミットされていないデータ

私の経験であなたの意見をテストするには、djangoのテストケースとテストクライアントは、通常あなたの95%を取得します。各テストはトランザクション内で実行され、要求(URLルーティング、ミドルウェア、ビューロード、テンプレート処理など)を模倣するテストクライアントを公開するため、非常に高速です。

TestCaseを使用すると、すべてのロジックとデータベースのやりとりを忠実にテストする必要がありますが、スーパーバイザー、nginx、uwsgi、djangoアプリが正常に機能している場合でも、 TestCaseを使用して広範なカバレッジを持つ場合、上記のサービスが正しく通信できることを確認するには、単純な統合/スモークテストで十分です。つまり、スタックを起動し、テストするステータスページを表示します - >スーパーバイザー - > Nginx - > uwsgi - > django - > DB - >バックアウト。


あり、純粋に機能テストのための多くのオプションがデフですが、Djangoは信頼性の高い、迅速な、使いやすいようにしてアプリケーションを検証するツールを提供する場合、フレーク状のタイムリーでのテストは、レベルを維持する理由?

あなたは、ブラウザベースのテストのためにブラウザに利用できるようにするサーバーが必要な場合は、私はAPIのメソッドとしてfixutre作成方法を暴露して大きな成功を収めてきた豊富な機能テストを記述する必要がある場合は、DjangoはLiveServerTestCase

を提供します。このようにして、あなたのテストはスタック、任意のスタックに対して実行されます。この場合、ローカルで起動するテストスタックに対してテストが実行されますが、テストは独立しているため、QAやステージング、あるいはプロダクトスタックに対して実行できます。

+0

私はあなたのポイントのほとんどを理解しました。 DjangoのTestCasesクラスでは、プロジェクトのテスト方法の80%しかカバーしていませんが、私はあなたの助言に従って、まずスタックレスのテストを試みます。ありがとう。 – Fian

2

現実のビューではWebサーバーによって駆動する必要があるにもかかわらず、djangoビューをテストするためにWebサーバーを使用しないでください。リクエスト/レスポンスの動作をテストするには、djangoテストクライアントを使用する必要があります。その上で

>>> from django.test import Client 
>>> c = Client() 
>>> response = c.post('/login/', {'username': 'john', 'password': 'smith'}) 
>>> response.status_code 
200 
>>> response = c.get('/customer/details/') 
>>> response.content 
b'<!DOCTYPE html...' 

は、ドキュメントはGETPOST要求を行う方法と理にかなっているなど、ビューの応答、希望をテストする方法を詳細に説明しますDjango docは引用、そのことについて優れた例があります。

+0

有効なポイント。 "Djangoテストクライアント"のようなツールが私のテストニーズを100%カバーしていないとしても、私はそれを想定どおりに使用します。それから私はスタック全体をテストする方法を理解します。ありがとう。 – Fian

関連する問題