Вопрос или проблема
Я пишу модульные тесты приложений каталога электронных книг в Django 5. Страница создания книги использует встроенный CreateView. Код класса выглядит так:
class BookCreate(SuccessMessageMixin, PermissionRequiredMixin, CreateView):
model = Book
fields = ['title', 'author', 'genre', 'publisher', 'pages', 'cover', 'summary']
template_name="books/add_book.html"
permission_required = 'catalog.add_book'
permission_denied_message="Недостаточно прав для добавления книги"
success_message="Книга успешно добавлена"
success_url = reverse_lazy('add-book')
Это работает следующим образом: пользователь заполняет данные о книге, нажимает кнопку отправки, затем страница перенаправляется на ту же страницу, плюс на странице отображается сообщение, указанное в атрибуте success_message класса
Для тестирования я использую MessagesTestMixin, как описано в документации Django. Вот код модульного теста:
class TestBookCreateView(MessagesTestMixin, TestCase):
@classmethod
def setUpTestData(cls):
cls.test_user = User.objects.create_user(
email="[email protected]",
username="John",
password='Fiesta123'
)
cls.add_book_permission = Permission.objects.get(codename="add_book")
def setUp(self):
login = self.client.login(username="Ivan", password='Fiesta123')
self.test_user.user_permissions.set([self.add_book_permission])
def test_if_view_success_message_attached(self):
author = Author.objects.create(
first_name="Charles",
last_name="Dickens"
)
genre = Genre.objects.create(
genre="Novel"
)
book_data = {
'title': 'Великие надежды',
'author': author,
'genre': genre
}
response = self.client.post(reverse('add-book'), data=book_data, follow=True)
self.assertMessages(response, 'Книга успешно добавлена')
Тест не проходит, я вижу пустой список в результатах вместо сообщения. Однако в приложении сообщение успешно передается в шаблон страницы, и я вижу его на странице после создания книги. Хранилище сообщений в settings.py не задано явно, поэтому приложение использует storage.fallback.FallbackStorage, предоставляемое по умолчанию.
Так в чем может быть проблема в этом случае и какие существуют хорошие практики тестирования сообщений в Django CBV?
Ответ или решение
Проблемы с тестированием сообщений в Django 5 CreateView
Создание юнит-тестов для вашего приложения — важный аспект разработки, особенно когда речь идет о функционале, который взаимодействует с пользователем, как в случае с добавлением книги в вашем ebook каталоге. Давайте разберемся, почему ваш тест на успешное сообщение при создании книги не проходит.
Причины проблемы
Ваш код выглядит в целом правильно, и он должен работать, как ожидается. Однако существуют несколько нюансов, которые могут привести к проблемам с тестированием сообщений.
-
Аутентификация пользователя: В методе
setUp
вы логините пользователя, но, если вы хотите проверить сообщения для конкретного пользователя, убедитесь, что он действительно логинится корректно. ИспользуйтеassertTrue(login)
после вызоваself.client.login(...
, чтобы убедиться, что логин выполнен успешно. -
Настройка прав доступа: В вашем методе
setUp
вы настроили права дляtest_user
, но проверка логина выполняется для пользователя с именем “Ivan”. Убедитесь, что вы логинитесь под тем пользователем, который имеет необходимые права. Например:self.client.login(username=self.test_user.username, password='Fiesta123')
-
Отправка данных: В вашем запросе POST вы можете не передавать необходимые поля. Поскольку
field
содержит множество полей, такие какcover
иsummary
, убедитесь, что все нужные данные отправляются вbook_data
. Для простоты теста можно указать значения по умолчанию. -
Подход к тестированию сообщений: Иногда
MessageTestMixin
не может определить сообщения, если они не привязаны к текущему запросу. Обратите внимание на то, как вы получаете и проверяете сообщения. Например, попробуйте следующее:messages = list(get_messages(response.wsgi_request)) self.assertIn('Book successfully added', [m.message for m in messages])
Рекомендации по тестированию сообщений в Django CBV
Вот некоторые лучшие практики, которые помогут вам улучшить тестирование сообщений:
-
Проверяйте все необходимые поля: Убедитесь, что все поля модели, которые глобально обязательны, присутствуют в данных, передаваемых через форму, даже если вы не хотите их тестировать в данном конкретном случае.
-
Убедитесь в правильной аутентификации и правам пользователя: Всегда проверяйте, что пользователю действительно предоставлены необходимые права, и что он аутентифицирован перед выполнением действий, которые должны вызывать сообщения.
-
Чистота тестов: Создавайте отдельные тестовые случаи для проверки сообщений, чтобы не смешивать их с другими бизнес-логиками. Это делает ваши тесты более читаемыми и управляемыми.
-
Использование
assertCountEqual
: При тестировании сообщений используйтеassertCountEqual
, чтобы проверить, что количество и содержание сообщений совпадает с ожидаемыми.
Заключение
Ваша проблема с тестированием сообщений при использовании Django CreateView может быть связана с неправильной аутентификацией пользователя, не полным набором данных или неправильной реализацией тестов. Применяя вышеприведенные рекомендации и исправляя ошибки, вы сможете добиться успешного прохождения тестов для добавления сообщений. Это важно как для самого приложения, так и для уверенности в его стабильной работе.
Если какие-либо вопросы останутся, всегда можно обратиться к документации Django для получения дополнительных рекомендаций или советов по подготовке тестов.