Django测试框架中的login()

kev*_*vin 35 python authentication testing django login

我已经开始使用Django的测试框架,一切正常,直到我开始测试经过身份验证的页面.

为简单起见,我们假设这是一个测试:

class SimpleTest(TestCase):
    def setUp(self):
        user = User.objects.create_user('temporary', 'temporary@gmail.com', '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'], 'temporary@gmail.com')
Run Code Online (Sandbox Code Playgroud)

在我运行此测试后,它失败了,我看到login()的打印返回值返回True,但是response.content被重定向到登录页面(如果登录失败,则认证装饰器重定向到登录页面).我在装饰器中设置了一个断点来进行身份验证:

def authenticate(user):
    if user.is_authenticated():
        return True
    return False
Run Code Online (Sandbox Code Playgroud)

它确实返回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})
Run Code Online (Sandbox Code Playgroud)

当然,如果我尝试通过应用程序登录(在测试之外),一切正常.

Fil*_*kić 31

问题是你没有传递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', 'temporary@gmail.com', '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'], 'temporary@gmail.com')
Run Code Online (Sandbox Code Playgroud)


Dav*_*ver 12

使用通过在测试期间评估任何类型的身份验证的自定义身份验证后端通常很有用:

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)
Run Code Online (Sandbox Code Playgroud)

然后,在测试期间,添加yourapp.auth_backends.TestcaseUserBackend到您的AUTHENTICATION_BACKENDS:

AUTHENTICATION_BACKENDS = [
    "akindi.testing.auth_backends.TestcaseUserBackend",
]
Run Code Online (Sandbox Code Playgroud)

然后,在测试期间,您可以简单地调用:

from django.contrib.auth import login
user = User.objects.get(…)
login(testcase_user=user)
Run Code Online (Sandbox Code Playgroud)