Django - тест не пройден, хотя ссылка работает - PullRequest
0 голосов
/ 03 июня 2018

Я нашел отличный учебник, написанный на Django-1.11.Но я решил использовать текущую версию (2.0.5) и попытаться адаптировать учебник.Если мне это удастся, я бы хотел предоставить обновленную версию учебника позже.

Изменяя некоторые вещи, которые устарели, я уже преуспел с помощью официальной документации Django.Но при написании некоторых тестов я столкнулся с трудностями.

Я не понимаю, почему я получаю эту 404 != 200 ошибку.

views.py

# ...
def board_topics(request, pk):
    board = get_object_or_404(Board, pk=pk)
    return render(request, "topics.html", {"board": board})

urls.py

# ...
urlpatterns = [
    path("boards/<int:pk>/", views.board_topics, name="board_topics"),
    path("home/", views.home, name="home"),
    path("admin/", admin.site.urls),
]

tests.py

# ...
class BoardTopicsTests(TestCase):
    def setUp(self):
        self.board = Board.objects.create(
            name="Django", description="Django discussion board"
        )

    # ...
    def test_board_topics_view_contains_link_back_to_homepage(self):
        board_topics_url = reverse("board_topics", kwargs={"pk": 1})
        response = self.client.get(board_topics_url)
        homepage_url = reverse("home")
        self.assertContains(
            response, 'href="{0}"'.format(homepage_url)
        )

Traceback

FAIL: test_board_topics_view_contains_link_back_to_homepage (boards.tests.BoardTopicsTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/.../boards/tests.py", line 52, in test_board_topics_view_contains_link_back_to_homepage
self.assertContains(response, 'href="{0}"'.format(homepage_url))
...
AssertionError: 404 != 200 : 
Couldn't retrieve content: Response code was 404 (expected 200)
----------------------------------------------------------------------
Ran 7 tests in 0.038s
FAILED (failures=1)

Интересно, почему я получаю эту ошибку, хотя я могу вызвать представления.Правильно ли я написал этот тест?

1 Ответ

0 голосов
/ 03 июня 2018

Ошибка, вероятно, вызвана тем, что нет элемента с первичным ключом pk=1.База данных обычно хранит в памяти «диспетчер идентификаторов».Это своего рода процедура, которая каждый раз, когда требуется автоматическое увеличение идентификатора, распределяет его и увеличивает счетчик.Но учтите, что если вы позже, например, удалите этот объект и создадите новый, вы не будете «повторно использовать» идентификатор, а просто возьмете следующий (некоторые базы данных вычисляют максимальное значение id, когдаони перезапускаются и продолжают считать с этого идентификатора.)

Независимо от того, как база данных фактически отправляет первичные ключи, вы не можете контролировать эту процедуру, поэтому небезопасно делать предположения об этом.

Поэтому вам лучше получить атрибут pk сохраненного вами объекта Board:

class BoardTopicsTests(TestCase):
    def setUp(self):
        self.board = Board.objects.create(
            name="Django", description="Django discussion board"
        )

    # ...

    def test_board_topics_view_contains_link_back_to_homepage(self):
        board_topics_url = reverse("board_topics", kwargs={"pk": <b>self.board.pk</b>})
        response = self.client.get(board_topics_url)
        homepage_url = reverse("home")
        self.assertContains(response, 'href="{0}"'.format(homepage_url))

Когда вы запустите pytest (или другой инструмент тестирования), он будет запускать тесты до и после текущего тестового случаяи, следовательно, вы на самом деле не знаете, каково будет состояние диспетчера id, если он достигнет этого конкретного тестового примера.

Выше приведен особый случай ", делающего слишком много предположений о бэкэндах ».Одна из идей Django состоит в том, чтобы, например, иметь ORM, который является инвариантным для базы данных (в некоторой степени).Таким образом, это означает, что вы не должны делать предположений о том, как будет работать конкретная система баз данных, поскольку Django предназначен для простого переноса приложения из одной системы баз данных в другую и сохранения всего кода без изменений (например, Django ORM будет создавать различные запросы, которыеработа над новой системой баз данных).Делая такие предположения, вы в конечном итоге « зафиксируете себя в » в конкретной архитектуре, которая может быть опасной, если впоследствии потребности вашего приложения изменятся, и другая архитектура лучше подойдет для этих нужд.

...