Как написать модульный тест для представления 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() терпит неудачу и не перенаправляет, правильно?

770   2  

2 ответов:

NB NB!то, что я описываю ниже, не является строго "модульным тестом"; почти невозможно написать независимый модульный тест для кода представления Django. Это интеграционный тест...

вы правы, что есть несколько путей через ваш взгляд:

  1. GET или POST анонимным пользователем (следует перенаправить на страницу входа)
  2. GET или POST вошедшим в систему пользователем без профиля (должен поднять UserProfile.DoesNotExist исключения)
  3. GET при входе в систему пользователя (должен показать форму)
  4. POST вошедшим в систему пользователем с пустыми данными (должны показывать ошибки формы)
  5. POST вошедшим в систему пользователем с неверными данными (должен показывать ошибки формы)
  6. 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

    Ничего не найдено.