Подтвердить что ты не робот

Login() в структуре тестирования Django

Я начал использовать среду тестирования 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. Строка 4 в test_secure_page() правильно извлекает пользователя.

Это функция просмотра:

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

Конечно, если я попытаюсь войти в систему через приложение (вне теста), все будет хорошо.

4b9b3361

Ответ 1

Проблема в том, что вы не передаете 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]')

Ответ 2

Часто может быть полезно использовать пользовательский аутентификационный бэкэнд, который обходит любой вид аутентификации во время тестирования:

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.TestcaseUserBackend в свой AUTHENTICATION_BACKENDS:

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

Затем во время тестов вы можете просто позвонить:

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

Ответ 3

Аутентификация на основе токена: я находился в той же ситуации. Я обнаружил sloution, в котором фактически я генерировал пользователя для входа в систему с помощью метода setUp. Затем в тестовых методах я попытался получить токен и передать его вместе с данными запроса.

настроить:

1> создать пользователя ex.
self.pravesh = User.objects.create(email='[email protected]',first_name='Pravesh',last_name='aaabbb',phone='5456165156',phonecountrycode='91')

2> установить пароль для пользователя

Метод испытания:

1> создать клиента
ех.
client.login(email=self.pravesh.email, password=self.password)

2> получить токен (в случае аутентификации токена) ex
token = Token.objects.create(user=self.pravesh)

2> передать регистрационную информацию ex

'response = client.post(
        reverse('account:post-data'),
        data = json.dumps(self.data),
        HTTP_AUTHORIZATION='Token {}'.format(token),
        content_type = 'application/json'
    )'