Why is test case failing in Django when it returns True in Python intrepreter?

97 views Asked by At

When I run this code in the Python interpreter, it returns True:

>>> from movies.models import Movie
>>> movie_list = Movie.objects.all()
>>> bool(movie_list)
True

When I run my test case, python3 manage.py test movies, it fails:

from django.test import TestCase
from .models import Movie

class QuestionMethodTests(TestCase):

    def test_movie_list_empty(self):
        movie_list = Movie.objects.all()
        self.assertEqual(bool(movie_list), True)

What am I missing? Shouldn't the test pass?

2

There are 2 answers

0
warvariuc On

Because in tests you are using a temporary database which doesn't have the objects:

Tests that require a database (namely, model tests) will not use your “real” (production) database. Separate, blank databases are created for the tests.

Regardless of whether the tests pass or fail, the test databases are destroyed when all the tests have been executed.

It's dangerous to use the real database for tests. Especially that tests should be reproducible, on other machines too. You should use fixtures for tests. Look at factory_boy.

0
bakkal On

I see. Does that mean the test cases only test the code but can't use any of the actual database content in its tests?

By default no, and you don't want to mess with the actual DB anyway, there is a usual way to provide the initial objects for the tests (the actual source can differ, e.g. loading from a file)

from django.test import TestCase
from .models import Movie

class QuestionMethodTests(TestCase):

    def setUp(self):
        # You can create your movie objects here
        Movie.objects.create(title='Forest Gump', ...)

    def test_movie_list_empty(self):
        movie_list = Movie.objects.all()
        self.assertEqual(bool(movie_list), True)

The TestCase class also contains a setUpTestData method if you fancy that, https://docs.djangoproject.com/en/1.8/topics/testing/tools/#django.test.TestCase.setUpTestData

PS: test_movie_list_empty name sounds weird, cause it seems to test that the movie list is NOT empty