Django - 即使链接有效,测试也会失败

时间:2018-06-03 15:17:42

标签: python django python-3.x django-tests

我找到了一个用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))

回溯

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 :(得分:1)

可能是因为没有主键pk=1的元素而导致错误。数据库通常会在内存中存储“id调度程序”。某种例程,每次需要自动递增id时,分配一个,并递增计数器。但请注意,如果您稍后删除该对象并创建一个新对象,您将“重用”该标识符,而只需采用下一个(某些数据库将计算最大值{{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": self.board.pk}) response = self.client.get(board_topics_url) homepage_url = reverse("home") self.assertContains(response, 'href="{0}"'.format(homepage_url))(或其他测试工具)时,它将在当前测试用例之前和之后运行测试,因此,如果它到达此特定状态,您就不知道id调度程序的状态是什么测试用例。

以上是“对后端进行过多假设”的特例。 Django背后的一个想法是拥有一个数据库不变的ORM(在某种程度上)。因此,这意味着您不应该假设特定数据库系统将如何工作,因为Django旨在将应用程序从一个数据库系统轻松迁移到另一个数据库系统,并保持所有代码完整(Django ORM将构建不同的查询,在新的数据库系统上工作)。通过做出这样的假设,您最终会“将自己锁定在”中进入特定的体系结构,如果以后应用程序的需求发生变化,这可能会很危险,并且不同的体系结构更适合这些需求。