在Django测试框架中使用基本HTTP访问身份验证

时间:2011-03-31 04:50:05

标签: python django unit-testing http-authentication django-testing

对于我的一些Django视图,我创建了一个执行基本HTTP访问身份验证的装饰器。但是,在Django中编写测试用例时,我花了一些时间来研究如何对视图进行身份验证。这就是我做到的。我希望有人觉得这很有用。

6 个答案:

答案 0 :(得分:65)

以下是我的表现:

from django.test import Client
import base64
auth_headers = {
    'HTTP_AUTHORIZATION': 'Basic ' + base64.b64encode('username:password'),
}
c = Client()
response = c.get('/my-protected-url/', **auth_headers)

注意:您还需要创建一个用户。

答案 1 :(得分:29)

在您的Django TestCase中,您可以更新客户端默认值以包含HTTP基本身份验证凭据。

import base64
from django.test import TestCase

class TestMyStuff(TestCase):

    def setUp(self):
        credentials = base64.b64encode('username:password')
        self.client.defaults['HTTP_AUTHORIZATION'] = 'Basic ' + credentials

答案 2 :(得分:2)

对于python3,您可以对username:password字符串进行base64编码:

base64.b64encode(b'username:password')

这会返回字节,因此您需要将其转换为带有.decode('ascii')

的ASCII字符串

完整示例:

import base64

from django.test import TestCase


def test_authorized(self):
    headers = {
        'HTTP_AUTHORIZATION': 'Basic ' + base64.b64encode(b'username:password').decode("ascii")
    }
    response = self.client.get('/', **headers)
    self.assertEqual(response.status_code, 200)

答案 3 :(得分:1)

假设我有一个登录表单,我使用以下技术登录测试框架:

    client = Client()
    client.post('/login/', {'username': 'john.smith', 'password': 'secret'})

然后我在其他测试中携带client,因为它已经过身份验证。你对这篇文章有什么疑问?

答案 4 :(得分:1)

(python3)我正在测试中使用它:

credentials_string = '%s:%s' % ('invalid', 'invalid')
credentials = base64.b64encode(credentials_string.encode())
self.client.defaults['HTTP_AUTHORIZATION'] = 'Basic ' + credentials.decode()

以及以下内容:

import base64
[...]
type, auth = request.META['HTTP_AUTHORIZATION'].split(' ', 1)
auth = base64.b64decode(auth.strip()).decode()

答案 5 :(得分:0)

另一种方法是绕过Django Client()并改为使用Requests。

class MyTest(TestCase):
    def setUp(self):
        AUTH = requests.auth.HTTPBasicAuth("username", "password")

    def some_test(self):
        resp = requests.get(BASE_URL + 'endpoint/', auth=AUTH)
        self.assertEqual(resp.status_code, 200)