Проблема с тестированием сообщений в Django 5 CreateView

Вопрос или проблема

Я пишу модульные тесты приложений каталога электронных книг в 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 каталоге. Давайте разберемся, почему ваш тест на успешное сообщение при создании книги не проходит.

Причины проблемы

Ваш код выглядит в целом правильно, и он должен работать, как ожидается. Однако существуют несколько нюансов, которые могут привести к проблемам с тестированием сообщений.

  1. Аутентификация пользователя: В методе setUp вы логините пользователя, но, если вы хотите проверить сообщения для конкретного пользователя, убедитесь, что он действительно логинится корректно. Используйте assertTrue(login) после вызова self.client.login(..., чтобы убедиться, что логин выполнен успешно.

  2. Настройка прав доступа: В вашем методе setUp вы настроили права для test_user, но проверка логина выполняется для пользователя с именем “Ivan”. Убедитесь, что вы логинитесь под тем пользователем, который имеет необходимые права. Например:

    self.client.login(username=self.test_user.username, password='Fiesta123')
  3. Отправка данных: В вашем запросе POST вы можете не передавать необходимые поля. Поскольку field содержит множество полей, такие как cover и summary, убедитесь, что все нужные данные отправляются в book_data. Для простоты теста можно указать значения по умолчанию.

  4. Подход к тестированию сообщений: Иногда 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 для получения дополнительных рекомендаций или советов по подготовке тестов.

Оцените материал
Добавить комментарий

Капча загружается...