#1763 closed defect (wontfix)
Patch to enable in-memory testing of Django applications
| Reported by: | Owned by: | Adrian Holovaty | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | |
| Severity: | normal | Keywords: | |
| Cc: | gabor@… | Triage Stage: | Unreviewed |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Currently, Django doesn't have a nice way of unit-testing individual applications quickly it takes a long time to drop/recreate the backing database. There are a number of scripts on the web that *almost* let you replace the database with a SQLite in-memory database, but it doesn't work in all cases due to some tricky import problems in Django.
Basically - after the MR branch was merged, the following idiom crept into a lot of the Django code:
from django.db import connection
Unfortunately, in Python, that means that every module that invokes that line will create a module local reference to the connection. If the db module is reloaded with a sqlite in-memory database, all of the caller of "from django.db import connection" will *not* get the new database connection.
I have a patch for Django that will let you cleanly replace the django.db module in one shot.
Attachments (4)
Change History (9)
by , 20 years ago
| Attachment: | unittest.patch added |
|---|
by , 20 years ago
| Attachment: | test_env.2.py added |
|---|
A module that has an init_ramdb() function that will replace your database with a SQLite memory version
comment:1 by , 20 years ago
Sorry for the double attachment, they're the same file, but I hit enter by accident and submitted test_env.py without a comment.
Here's a sample usage of the test_env module.
13 def test_db():
14 '''
15 Test that the enviroment has a reference to the current database
16 connection
17 '''
18 test_env.init_ramdb()
19
20 today = datetime.date.today()
21 c = Contact(first_name='Victor', last_name='Ng', date_created=today)
22 c.save()
23
24 cur = django.db.connection.cursor()
25 cur.execute("select first_name, last_name, date_created from travel_contact") # where date_created = '%s'" % (toda y,))
26 rows = cur.fetchall()
27 assert len(Contact.objects.all()) == 1
28 assert len(rows) == 1
29 row = rows[0]
30 assert row[0] == 'Victor'
31 assert row[1] == 'Ng'
32 assert row[2] == today
33
34 test_env.init_ramdb()
35
36 cur = django.db.connection.cursor()
37 cur.execute("select first_name, last_name, date_created from travel_contact where date_created = '%s'" % (today,))
38 actual = len(cur.fetchall())
39 expected = 0
40 assert actual == expected
comment:2 by , 20 years ago
| Cc: | added |
|---|
by , 19 years ago
| Attachment: | db_fix.patch added |
|---|
Updated the patch sync with django svn head at revision 3046
comment:3 by , 19 years ago
| Type: | enhancement |
|---|
comment:4 by , 19 years ago
| Resolution: | → wontfix |
|---|---|
| Status: | new → closed |
| Type: | → defect |
Replacing the django.db module is very hackish and not Pythonic; we shouldn't encourage that.
comment:5 by , 19 years ago
I hope this doesn't sound snippy - but how should people unit test their Django application then?
Patch to Django to let you replace the django.db module cleanly to facilitate unit testing of applications