web-dev-qa-db-ja.com

Djangoテストフレームワークのlogin()

私はDjangoのテストフレームワークを使い始めましたが、認証されたページのテストを開始するまで、すべてが正常に機能していました。

簡単にするために、これはテストであるとしましょう:

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]')

このテストを実行すると失敗し、login()の戻り値を印刷するとTrueが返されますが、response.contentがログインページにリダイレクトされます(ログインに失敗した場合)認証デコレータはログインページにリダイレクトします)。認証を行うデコレータにブレークポイントを設定しました。

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

そして、それは本当に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})

もちろん、(テスト以外の)アプリケーションからログインしようとすると、すべてが正常に動作します。

35
kevin

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

また、おそらくlogin_requiredデコレータとTestCaseクラスに組み込まれたクライアント。

私はそれを次のように書き直します:

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

@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 = get_user_model()
        user = User.objects.create_user('temporary', '[email protected]', 'temporary')

    def test_secure_page(self):
        User = get_user_model()
        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]')
32
Filip Jukić

多くの場合、テスト中にあらゆる種類の認証をバイパスするカスタム認証バックエンドを使用すると便利です。

from Django.contrib.auth import get_user_model

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

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

次に、テスト中にyourapp.auth_backends.TestcaseUserBackendAUTHENTICATION_BACKENDSに追加します。

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

次に、テスト中に、次を呼び出すだけです。

from Django.contrib.auth import login
user = User.objects.get(…)
login(testcase_user=user)
12
David Wolever

トークンベースの認証:私も同じ状況でした。私は実際にsetUpメソッドでログイン用のユーザーを生成した解決策を見つけました。その後、テストメソッドの後半で、トークンを取得して、リクエストデータと一緒に渡しました。

setUp:

  1. ユーザーを作成する
self.pravesh = User.objects.create(
     email='[email protected]',
     first_name='Pravesh',
     last_name='aaabbb',
     phone='5456165156',
     phonecountrycode='91'
)
  1. ユーザーのパスワードを設定する
self.password = 'example password'
self.pravesh.set_password(self.password)

test_method:

  1. クライアントを作成する
client.login(email=self.pravesh.email, password=self.password)
  1. トークンを取得する(トークン認証の場合)
token = Token.objects.create(user=self.pravesh)
  1. ログイン情報を渡す
response = client.post(
    reverse('account:post-data'),
    data = json.dumps(self.data),
    HTTP_AUTHORIZATION='Token {}'.format(token),
    content_type = 'application/json'
)
1
OpenHub