Gesias
Gesias

Reputation: 778

Django test.TestCase vs unittest.TestCase

I am wondering a few things about best practices regarding supplying data for your tests.

From the docs

from django.test import TestCase
from myapp.models import Animal

class AnimalTestCase(TestCase):
    def setUp(self):
        Animal.objects.create(name="lion", sound="roar")
        Animal.objects.create(name="cat", sound="meow")

    def test_animals_can_speak(self):
        """Animals that can speak are correctly identified"""
        lion = Animal.objects.get(name="lion")
        cat = Animal.objects.get(name="cat")

Like the example above I want to save a few models in the setUp method of the testcase which I later use in the particular testcases. I could certainly provide a json fixture for this, but I rather create the models in the code for transparency this time since its very few.

When I use django.test.TestCase each individual test is running in a transaction according to the docs. But no data from my setUp() is present in the database. I ran it in a debugger and connect to the temp database and checked it.

When using django.utils.unittest.TestCase the data is present. Alas, the method is aggregating the data since its running for each individual test.

I understand why unittest.TestCase is aggregating the data due to not flushing the database. What I do not understand is why the data is not present when using django.test.TestCase. Even in the end of the setUp() method its still blank.

Is django.test.TestCase not supposed to save any data or am I doing something entirely wrong?

EDIT 1: Did a clean project with this and it started working as I suspected it should. The django.test.TestCase filled the database with the data in the setup() method for each individual run so I guess theres have to be something quite fishy with the setup on my part. I´ll apply Occam's razor and see if I can find out what it is.

EDIT 2: Cleaned out the models and tests files and ran the tests again. Setting the debugger to halt after the setUp() but theres still not anything in the database. The objects do have an pk and would assumably be saved to the database. Checked the ModelState object thats inherited to the Model and according to the adding attribute its saved to the database.

Added this debug code to the setUp() method:

from django.db import connections
    print connections.databases

{'default': {'ENGINE': 'django.db.backends.mysql', 
'NAME': 'test_DATABASE_temp', 'TEST_CHARSET': None, 
'TEST_COLLATION': None, 'HOST': 'localhost', 'USER': 'user', 
'TEST_NAME': None, 'PASSWORD': 'password}

But when adding:

print Animals.objects.all().count()

2

I get the response that there are in fact objects available. But where are they? Getting a bit obsessed with this now I must admit =).

I can proceed now, but still lacking a satisfying answer.

Upvotes: 3

Views: 1148

Answers (2)

bruno desthuilliers
bruno desthuilliers

Reputation: 77892

django.test.TestCase do a couple things for you, one of them being creating a test database (and destroying it once the test has completed). This is documented here : https://docs.djangoproject.com/en/stable/topics/testing/overview/#the-test-database

Upvotes: 1

blueFast
blueFast

Reputation: 44351

Django's django.test.TestCase does not commit the transaction, so it never appears in the database. The whole testcase is executed inside a big transaction, so that you can not check from outside what is happening to the database (since there is actually nothing at all happening to the database until the transaction is committed, which never happens)

Upvotes: 2

Related Questions