2011-09-09 10 views
27

私はDjangoのテストフレームワークを使い始めました。認証されたページのテストを開始するまではすべて正常に動作していました。簡単のためDjangoテストフレームワークのlogin()

、のは、これはテストですと言ってみましょう:

class SimpleTest(TestCase): 
    def setUp(self): 
     user = User.objects.create_user('temporary', '[email protected]', 'temporary') 

    def test_secure_page(self): 
     c = Client() 
     print c.login(username='temporary', password='temporary') 
     response = c.get('/users/secure/', follow=True) 
     user = User.objects.get(username='temporary') 
     self.assertEqual(response.context['email'], '[email protected]') 

私は、それが失敗し、このテストを実行すると、私は、ログインの印刷戻り値を(参照した後)は、を返します。 response.contentはログインページにリダイレクトされます(ログインが失敗した場合、認証デコレータはログインページにリダイレクトされます)。私は、認証を行うデコレータでブレークポイント入れている:

def authenticate(user): 
    if user.is_authenticated(): 
     return True 
    return False 

をし、それが本当にを返します。 test_secure_page()の4行目は、適切にユーザを取得します。

これはビュー関数である:私は、アプリケーション(テストの外)からログインしようとすると、当然のことながら

@user_passes_test(authenticate, login_url='/users/login') 
def secure(request): 
    user = request.user 
    return render_to_response('secure.html', {'email': user.email}) 

、すべてが正常に動作します。

+1

あなたがテストしているビューのコードを投稿してください。 –

+0

@ S.Lott私は自分のログインページをテストしていませんでしたが(私も同様でしたが、どちらもうまくいきませんでした)、システムの "安全な"部分の残りの部分です。そのため、login()を使ってみました。 – kevin

+1

@kevin。問題は、ログインするポストがクライアントによって使用されるクッキーを作成することです。クッキーなし、安全なアクセスなし。 AFAIK、 'login()'関数はクッキーを作成してクライアントに返しません。あなたはDjangoのドキュメントの例を再現し、それらがあなたのために働くかどうかを調べることができますか? –

答えて

25

問題は、RequestContextをテンプレートに渡していないことです。

また、login_requiredデコレータとクライアントをTestCaseクラスに組み込む必要があります。

私はこのようにそれを書き直したい:

#views.py 
from django.contrib.auth.decorators import login_required 
from django.shortcuts import render 

@login_required(login_url='/users/login') 
def secure(request): 
    user = request.user 
    return render(request, 'secure.html', {'email': user.email}) 



#tests.py 
class SimpleTest(TestCase): 
    def setUp(self): 
     user = User.objects.create_user('temporary', '[email protected]', 'temporary') 

    def test_secure_page(self): 
     self.client.login(username='temporary', password='temporary') 
     response = self.client.get('/manufacturers/', follow=True) 
     user = User.objects.get(username='temporary') 
     self.assertEqual(response.context['email'], '[email protected]') 
+1

なぜRequestContextを渡さないと問題になるはずだと思いますか?(コンテキストはrender_to_response()に与えられます)これは、ブラウザから呼び出されたときにテストフレームワークの外で動作します(btw、私はRequestContextを渡そうとしましたが、同じことが起こります)。また、ビューが入力される前に認証が行われます。 @login_requiredとTestCaseクラスのクライアントも試しましたが、同じことが繰り返されます。 – kevin

+0

私はそれを変更して仕事をしました:self.assertEqual(response.context ['user']。email、 '[email protected]') – cor

10

多くの場合、テスト中の認証の任意の並べ替えをbypassessカスタム認証バックエンドを使用することが有用であり得る:

from django.contrib.auth.models import User 

class TestcaseUserBackend(object): 
    def authenticate(self, testcase_user=None): 
     return testcase_user 

    def get_user(self, user_id): 
     return User.objects.get(pk=user_id) 

次に、テスト中、あなたのAUTHENTICATION_BACKENDSyourapp.auth_backends.TestcaseUserBackendを追加します。

AUTHENTICATION_BACKENDS = [ 
    "akindi.testing.auth_backends.TestcaseUserBackend", 
] 

を次に、ドゥリンgテストでは、単に電話することができます:

from django.contrib.auth import login 
user = User.objects.get(…) 
login(testcase_user=user) 
+0

優れた答え。 –

+1

':login()には予想外のキーワード引数 'testcase_user''がありますか? – intelis

+0

'login'は' django.contrib.auth'からのものです(編集された記事を参照)?そして、あなたはバックエンドが正しく追加されていると確信していますか? –

関連する問題