Почему SimpleTestCase.assertContains возвращает False?
Выполняю тестирование удаления задач (сущность в БД) авторизованным и неавторизованным пользователями:
def test_delete_by_unauthorized_user(self): """Попытка удалить задачу неавторизованным пользователем.""" route = reverse('delete_task', args=[self.task.id]) redirect_url = f'/login/?next=/tasks/{self.task.id}/delete/' # можно ли использовать route? response = self.client.get(route, follow=True) self.assertRedirects(response, redirect_url) # self.assertEqual(get_message_text(response), _("You are not logged in! Please log in.")) self.assertContains(response, _("You are not logged in! Please log in.")) response = self.client.post(route, follow=True) self.assertRedirects(response, redirect_url) # self.assertEqual(get_message_text(response), _("You are not logged in! Please log in.")) self.assertContains(response, _("You are not logged in! Please log in.")) def test_delelete_by_authorized_user(self): """Удаление задачи авторизованным пользователем.""" tasks_count = Tasks.objects.count() route = reverse('delete_task', args=[self.task.id]) self.client.force_login(self.user) template = 'tasks/delete.html' response = self.client.get(route) error_name = f"Ошибка: маршрут {route} ожидал шаблон {template}" self.assertTemplateUsed(response, template, error_name) response = self.client.post(route) self.assertRedirects(response, reverse('all_tasks')) self.assertEqual(Tasks.objects.count(), tasks_count - 1) # self.assertEqual(get_message_text(response), _("The task has been successfully deleted.")) self.assertContains(response, _("The task has been successfully deleted.")) |
def test_delete_by_unauthorized_user(self): """Попытка удалить задачу неавторизованным пользователем.""" route = reverse('delete_task', args=[self.task.id]) redirect_url = f'/login/?next=/tasks/{self.task.id}/delete/' # можно ли использовать route? response = self.client.get(route, follow=True) self.assertRedirects(response, redirect_url) # self.assertEqual(get_message_text(response), _("You are not logged in! Please log in.")) self.assertContains(response, _("You are not logged in! Please log in.")) response = self.client.post(route, follow=True) self.assertRedirects(response, redirect_url) # self.assertEqual(get_message_text(response), _("You are not logged in! Please log in.")) self.assertContains(response, _("You are not logged in! Please log in.")) def test_delelete_by_authorized_user(self): """Удаление задачи авторизованным пользователем.""" tasks_count = Tasks.objects.count() route = reverse('delete_task', args=[self.task.id]) self.client.force_login(self.user) template = 'tasks/delete.html' response = self.client.get(route) error_name = f"Ошибка: маршрут {route} ожидал шаблон {template}" self.assertTemplateUsed(response, template, error_name) response = self.client.post(route) self.assertRedirects(response, reverse('all_tasks')) self.assertEqual(Tasks.objects.count(), tasks_count - 1) # self.assertEqual(get_message_text(response), _("The task has been successfully deleted.")) self.assertContains(response, _("The task has been successfully deleted."))
Закомментированные строки - старый способ проверки появления flash-сообщения с которым тесты успешно проходили. Но я решил его поменять на assertContains. В первой функции test_delete_by_unauthorized_user() тесты проходят успешно. Но во втором не проходят, сообщая:
AssertionError: 302 != 200 : Couldn't retrieve content: Response code was 302 (expected 200) |
AssertionError: 302 != 200 : Couldn't retrieve content: Response code was 302 (expected 200)
Я проверил, какие статусы возвращает сервер:
Удаление задачи Неавторизованный: [04/Apr/2024 10:28:21] "GET /tasks/2/delete/ HTTP/1.1" 302 0 [04/Apr/2024 10:28:21] "GET /login/?next=/tasks/2/delete/ HTTP/1.1" 200 11533 Авторизованный: [04/Apr/2024 10:31:40] "POST /tasks/6/delete/ HTTP/1.1" 302 0 [04/Apr/2024 10:31:48] "GET /tasks/ HTTP/1.1" 200 14764 |
Удаление задачи Неавторизованный: [04/Apr/2024 10:28:21] "GET /tasks/2/delete/ HTTP/1.1" 302 0 [04/Apr/2024 10:28:21] "GET /login/?next=/tasks/2/delete/ HTTP/1.1" 200 11533 Авторизованный: [04/Apr/2024 10:31:40] "POST /tasks/6/delete/ HTTP/1.1" 302 0 [04/Apr/2024 10:31:48] "GET /tasks/ HTTP/1.1" 200 14764
Да, в функции test_delete_by_unauthorized_user() запрос и вправду возвращает 302 статус, но ведь и первая функция его возвращает (test_delete_by_authorized_user()). Тем не менее, она успешно проходит тесты. Почему так происходит?
Дополнительно:
Ответы:
Я нашел решение проблемы.
Я не установил во второй функции в метод, выполняющий запрос - self.client.post() аргумент follow=True.
Т.е. у меня сохранялся только первый адрес и состояние - ('/tasks/6/delete/', 302), а не все промежуточные адреса и коды состояния.
Я правильно понял механизм assertContains - он проходит по всем полученным в ходе запроса адресам и состояниям и проверяет, что response произвел данный status_code и что text появляется в его content. И если он получил хоть одно совпадение, то возвращает True?
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
SimpleTestCase.assertContains возвращает False, когда метод не находит указанное значение в строке или массиве. Это может произойти по нескольким причинам, и важно учитывать следующие моменты:
1. Проверьте правильность написания искомого значения. Убедитесь, что вы правильно указали ожидаемое значение в методе assertContains.
2. Убедитесь, что вы используете метод assertContains в соответствии с его синтаксисом. Например, если вы хотите проверить наличие подстроки в строке, убедитесь, что вы указали искомую подстроку в нужном порядке.
3. Проверьте тип данных, с которым вы работаете. Если вы пытаетесь найти значение в массиве, убедитесь, что массив содержит искомое значение и что тип данных совпадает.
Пример использования SimpleTestCase.assertContains для поиска подстроки в строке на языке PHP:
$string = "Hello, World!"; $this->assertContains("Hello", $string);
Если все указанные выше моменты проверены и вы все равно получаете False в результате выполнения метода assertContains, возможно, проблема заключается в других частях вашего кода или внешних факторах. Рекомендуется более детально изучить контекст выполнения теста и проверить другие возможные причины, влияющие на результат.