Search code examples
djangodjango-testingdjango-tests

Django 2.0 TestCase unexpected creation of Model objects for every test


I have some tests and I need one Board object which I created with Board.objects.create() to have one Object with the primary key 1. But i have figured out, that there are a new object for every test, so i there I have for example 'pk': 5. If i add more tests the 'pk': 5 could be wrong, because it change to 'pk': 6. How is it possible to create only one Board object with 'pk': 1 for all tests?

I am using Django 2.0.3

from django.test import TestCase
from django.urls import reverse, resolve
from .views import home, board_topics, new_topic
from .models import Board

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

    def test_board_topics_view_success_status_code(self):
        url = reverse('boards:board_topics', kwargs={'pk': 5})
        response = self.client.get(url)
        self.assertEquals(response.status_code, 200)

    def test_board_topics_view_not_found_status_code(self):
        url = reverse('boards:board_topics', kwargs={'pk': 99})
        response = self.client.get(url)
        self.assertEquals(response.status_code, 404)

    def test_board_topics_url_resolves_board_topics_view(self):
        view = resolve('/boards/1/')
        self.assertEquals(view.func, board_topics)

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

    def test_board_topics_view_contains_navigation_links(self):
        board_topics_url = reverse('boards:board_topics', kwargs={'pk': 2})
        homepage_url = reverse('boards:home')
        new_topic_url = reverse('boards:new_topic', kwargs={'pk': 2})

        response = self.client.get(board_topics_url)

        self.assertContains(response, 'href="{0}"'.format(homepage_url))
        self.assertContains(response, 'href="{0}"'.format(new_topic_url))

Solution

  • You shouldn't rely on the primary key of the created objects. In this case, you can store the board as an attribute,

    def setUp(self):
        self.board = Board.objects.create(name='Django', description='Django board.')
    

    then use its pk in the test.

    def test_board_topics_view_success_status_code(self):
        url = reverse('boards:board_topics', kwargs={'pk': self.board.pk})
    

    This will make your test suite more robust. At the moment, your tests could fail if you run a subset of the tests, or run them in a different order.