Как можно протестировать пользовательские представления ошибок в django?
В документации Django приводится следующий пример для тестирования пользовательских представлений ошибок.
С учетом следующего примера, как вы собираетесь тестировать пользовательские server_error
и csrf_failure
представления? Я пытался запустить представление ошибки, используя несколько различных django.core.exceptions
, однако пользовательское представление ошибки никогда не запускается.
Возврат HTTPResponse дает ошибку AssertionError: No templates used to render the response
, что вполне логично. Однако когда я пытаюсь вывести ошибку, которая должна вызвать ошибку сервера, например raise ImproperlyConfigured
, ошибка просто выводится в тесте.
Тестирование на отказ CSRF - это уже другая история, поскольку я чувствую, что даже не приблизился к этому.
# views.py
from django.views import defaults
from django.views.csrf import csrf_failure as csrf_failure_default
def server_error(request):
template_name = 'wholesale/500.html'
return defaults.server_error(
request,
template_name=template_name,
)
def csrf_failure(request, reason=''):
template_name = 'wholesale/403_csrf.html'
return csrf_failure_default(
request,
reason=reason,
template_name=template_name,
)
# tests.py
from django.test import TestCase, override_settings
from . import views
def page_not_found_view(request):
raise Http404
def server_error_view(request):
# raise ImproperlyConfigured
return HttpResponseServerError()
def bad_request_view(request):
raise BadRequest
def permission_denied_view(request):
raise PermissionDenied
def csrf_failure_view(request):
return HttpResponse(status=HTTPStatus.FORBIDDEN)
urlpatterns = [
path('404/', page_not_found_view),
path('500/', server_error_view),
path('400/', bad_request_view),
path('403/', permission_denied_view),
path('403_csrf/', csrf_failure_view),
]
handler404 = views.page_not_found
handler500 = views.server_error
handler400 = views.bad_request
handler403 = views.permission_denied
@override_settings(ROOT_URLCONF=__name__)
class CustomErrorViewTestCase(TestCase):
def test_page_not_found_view(self):
response = self.client.get('/404/')
self.assertEqual(response.status_code, HTTPStatus.NOT_FOUND)
self.assertTemplateUsed(response, 'wholesale/404.html')
def test_server_error_view(self):
response = self.client.get('/500/')
self.assertEqual(response.status_code, HTTPStatus.INTERNAL_SERVER_ERROR)
self.assertTemplateUsed(response, 'wholesale/500.html')
def test_bad_request_view(self):
response = self.client.get('/400/')
self.assertEqual(response.status_code, HTTPStatus.BAD_REQUEST)
self.assertTemplateUsed(response, 'wholesale/400.html')
def test_permission_denied_view(self):
response = self.client.get('/403/')
self.assertEqual(response.status_code, HTTPStatus.FORBIDDEN)
self.assertTemplateUsed(response, 'wholesale/403.html')
def test_csrf_failure_view(self):
response = self.client.get('/403_csrf/')
self.assertEqual(response.status_code, HTTPStatus.FORBIDDEN)
self.assertTemplateUsed(response, 'wholesale/403_csrf.html')
Я нашел ответ в документации в разделе создание запросов.
Аргумент raise_request_exception позволяет контролировать, должны ли исключения, возникающие во время запроса, также возникать в тесте. По умолчанию значение True.
Мое решение - переопределить это значение и установить его на False
.
def test_custom_server_error_view(self):
server_error_client = Client(raise_request_exception=False)
response = server_error_client.get('/500/')
self.assertEqual(response.status_code, HTTPStatus.INTERNAL_SERVER_ERROR)
self.assertTemplateUsed(response, 'wholesale/500.html')
Аналогичная настройка может быть использована для проверки отказа CSRF.
def test_custom_csrf_failure_view(self):
csrf_client = Client(enforce_csrf_checks=True)
response = csrf_client.post('/403_csrf/')
self.assertEqual(response.status_code, HTTPStatus.FORBIDDEN)
self.assertTemplateUsed(response, 'wholesale/403_csrf.html')