Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#31299 closed Bug (invalid)

DB not flushed between TestCases

Reported by: Lokesh Gurram Owned by: ChillarAnand
Component: Testing framework Version: 2.2
Severity: Normal Keywords: TestCases, Fixtures
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Consider the case where I have two fixtures and two different TestCase classes that use them.

fixture1.json

[
{
    "model": "app1.user",
    "pk": 1,
    "fields": {
        "password": "",
        "last_login": null,
        "is_superuser": false,
        "username": "tesuser1",
        "first_name": "",
        "last_name": "",
        "is_staff": false,
        "is_active": true,
        "date_joined": "2020-02-21T12:59:17.302Z",
        "email": null,
        "groups": [],
        "user_permissions": []
    }
}
]

fixture2.json

[
{
    "model": "app1.user",
    "pk": 2,
    "fields": {
        "password": "",
        "last_login": null,
        "is_superuser": false,
        "username": "testuser2",
        "first_name": "",
        "last_name": "",
        "is_staff": false,
        "is_active": true,
        "date_joined": "2020-02-21T12:59:17.302Z",
        "email": null,
        "groups": [],
        "user_permissions": []
    }
}
]

Here are my test cases

class Test1(TestCase):
    fixtures = ['fixture1.json']

    @classmethod
    def tearDownClass(cls):
        super(TestCase, cls).tearDownClass()

    def test_demo(self):
        u = User.objects.get(username='testuser1')
        #some testing

class Test2(TestCase):
    fixtures = ['fixture2.json']

    @classmethod
    def tearDownClass(cls):
        super(TestCase, cls).tearDownClass()

    def test_demo2(self):
        try:
            u = User.objects.get(username='testuser1')
            print("Found him")
            #Some testing
        except:
            pass

I wouldn't expect to find testuser1 in my second test case as the fixtures for it doesn't have that particular user.

From django documentation:
At the start of each test, before setUp() is run, Django will flush the database, returning the database to the state it was in directly after migrate was called.

Change History (3)

comment:1 by ChillarAnand, 5 years ago

Owner: changed from nobody to ChillarAnand
Status: newassigned

What command are you using to run the tests? Is this happening with a new django project?

I created a new django project with the above fixtures and tests. It is working as expected?

# test1
test_demo (tests.test_user.Test1) ... <QuerySet [<User: tesuser1>]>

# test2
test_demo2 (tests.test_user.Test2) ... <QuerySet [<User: testuser2>]>

comment:2 by Simon Charette, 5 years ago

Resolution: invalid
Status: assignedclosed

You're explicitly calling super(TestCase, cls).tearDownClass() which skips fixtures teardown.

Please use TicketClosingReasons/UseSupportChannels for further assitance

comment:3 by Lokesh Gurram, 5 years ago

If I have more than one TestCase using the same fixture, loading data between test cases raises unique constraint violation error

class Test1(TestCase):
    fixtures = ['fixture.json']

    def test_demo(self):
        u = User.objects.get(username='testuser1')
        #some testing

class Test2(TestCase):
    fixtures = ['fixture.json']

    def test_demo2(self):
        #some testing
        pass

where my fixture.json is
Profile table has a one-to-one relation with User table.

[
{
    "model": "app1.user",
    "pk": 1,
    "fields": {
        "password": "",
        "last_login": null,
        "is_superuser": false,
        "username": "testuser1",
        "first_name": "",
        "last_name": "",
        "is_staff": false,
        "is_active": true,
        "date_joined": "2020-02-21T12:59:17.302Z",
        "email": null,
        "groups": [],
        "user_permissions": []
    }
},
{
    "model": "app1.profile",
    "pk": 1,
    "fields": {
        "user": 1,
        "firebaseID": null,
        "phone": null,
        "completed_till": 0,
    }
}
]

Running the each Test Case separately works fine. But when run them in one go, first Test case goes through and before second test case executes, I get this error -

django.db.utils.IntegrityError: Problem installing fixture 'C:\...\app1\fixtures\fixture.json': Could not load app1.Profile(pk=1): duplicate key value violates unique constraint "app1_profile_user_id_key"

Making an explicit call to tearDownClass helped in fixing this issue but it gave the problem I first posted here.

Any idea why the DB is not completely cleared before trying to load the fixtures for the next TestCase. I tested this with Django 2.2 on Postgres 10/12. The problem persists in both.
Interestingly though testing on SQLite doesn't give any problem.

Last edited 5 years ago by Lokesh Gurram (previous) (diff)
Note: See TracTickets for help on using tickets.
Back to Top