Как написать модульный тест для представления django?
у меня есть проблемы с пониманием того, как модульные тесты должны быть разработаны для django.
С моей точки зрения тестирование всего вида за один раз кажется невозможным. Нам необходимо проводить различие между пред-и пост-состояниями запроса. Но я понятия не имею, как это сделать. Есть ли реальный пример из жизни?
глядя на документацию примеры слишком упрощены и сосредоточены только на модели.
@login_required
def call_view(request, contact_id):
profile = request.user.get_profile()
if request.POST:
form = CallsForm(profile.company, request.POST)
if form.is_valid()
return HttpResponseRedirect('/contact/' + contact_id + '/calls/')
else:
form = CallsForm(profile.company, instance=call)
variables = RequestContext(request, {'form':form}
return render_to_response('conversation.html', variables)
обновление:
попытка сделать успешную тестовую работу, но она все еще терпит неудачу:
def test_contact_view_success(self):
# same again, but with valid data, then
self.client.login(username='username1', password='password1')
response = self.client.post('/contact/add/', {u'last_name': [u'Johnson'], })
self.assertRedirects(response, '/')
сообщение об ошибке:
AssertionError: Response didn't redirect as expected: Response code was 200 (expected 302)
Я думаю, это потому, что form.is_valid() терпит неудачу и не перенаправляет, правильно?
2 ответов:
NB NB!то, что я описываю ниже, не является строго "модульным тестом"; почти невозможно написать независимый модульный тест для кода представления Django. Это интеграционный тест...
вы правы, что есть несколько путей через ваш взгляд:
GETилиPOSTанонимным пользователем (следует перенаправить на страницу входа)GETилиPOSTвошедшим в систему пользователем без профиля (должен поднятьUserProfile.DoesNotExistисключения)GETпри входе в систему пользователя (должен показать форму)POSTвошедшим в систему пользователем с пустыми данными (должны показывать ошибки формы)POSTвошедшим в систему пользователем с неверными данными (должен показывать ошибки формы)POSTпри входе в систему пользователя с допустимыми данными (следует перенаправить)тестирование 1 это просто испытания
@login_required, так что вы можете пропустить его. Я, как правило, проверить его в любом случае (на всякий случай Я или кто-то еще забыл использовать этот декоратор).я не уверен, что случай отказа (страница ошибки 500) в 2 это то, что вы действительно хотите. Я бы понял, что вы хотите, чтобы произошло вместо этого (возможно использовать
get_or_create()иDoesNotExistисключение и создать новый профиль, который путь).в зависимости от того, сколько пользовательской проверки у вас есть,4 может действительно не нужно быть испытанным.
в любом случае, учитывая все из вышесказанного я бы сделал что-то вроде:
from django.test import TestCase class TestCalls(TestCase): def test_call_view_denies_anonymous(self): response = self.client.get('/url/to/view', follow=True) self.assertRedirects(response, '/login/') response = self.client.post('/url/to/view', follow=True) self.assertRedirects(response, '/login/') def test_call_view_loads(self): self.client.login(username='user', password='test') # defined in fixture or with factory in setUp() response = self.client.get('/url/to/view') self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'conversation.html') def test_call_view_fails_blank(self): self.client.login(username='user', password='test') response = self.client.post('/url/to/view', {}) # blank data dictionary self.assertFormError(response, 'form', 'some_field', 'This field is required.') # etc. ... def test_call_view_fails_invalid(self): # as above, but with invalid rather than blank data in dictionary def test_call_view_fails_invalid(self): # same again, but with valid data, then self.assertRedirects(response, '/contact/1/calls/')очевидно, что недостатком здесь является жестко закодированные URL-адреса. Вы могли бы либо использовать
reverse()в ваших тестах или построить запросы с помощьюRequestFactoryи вызовите свои представления как методы (а не по URL). С последним методом, однако, вам все равно нужно использовать жестко закодированные значения илиreverse()для проверки целей перенаправления.надеюсь, что это помогает.
Django поставляется с тестовым клиентом, который может быть использован для тестирования полного цикла запроса / ответа:документы содержит пример выполнения запроса get для данного url-адреса и утверждения кода состояния, а также контекста шаблона. Вам также понадобится тест, который делает сообщение и утверждает успешное перенаправление, как ожидалось.
Comments