In the unit tests that I wrote, I provide a test fixture for each TestCase. However, I keep getting duplicate (IntegrityError) when it runs in the test suite.
So, I am wondering, isn’t the database supposed to be created and populated at the beginning of each TestCase and after each test has be executed in that TestCase so that I can provide a different fixture for each TestCase?
Edit: added test code
class DashboardTestCase(TestCase):
fixtures = ['initial.json']
def setUp(self):
u = User(username='su')
u.save()
self.name = "Test Dashboard"
self.slug = "test-dashboard"
self.description = "Test Description"
self.fiscal_year = "2011"
self.region = "Test Region"
self.review_date = "2010-08-01"
self.date_completed = "2009-03-15"
self.prepared_by = "Test User"
self.dashboard = Dashboard(name=self.name, description=self.description, fiscal_year=self.fiscal_year,
region=self.region, review_date=self.review_date, date_completed=self.date_completed,
prepared_by=self.prepared_by)
self.dashboard.save()
def testDashboardName(self):
self.assertEqual(self.dashboard.name, self.name)
def testDashboardDescription(self):
self.assertEqual(self.dashboard.description, self.description)
def testDashboardFiscalYear(self):
self.assertEqual(self.dashboard.fiscal_year, self.fiscal_year)
def testDashboardRegion(self):
self.assertEqual(self.dashboard.region, self.region)
def testDashboardReviewDate(self):
self.assertEqual(self.dashboard.review_date, self.review_date)
def testDashboardDateCompleted(self):
self.assertEqual(self.dashboard.date_completed, self.date_completed)
def testDashboardPreparedBy(self):
self.assertEqual(self.dashboard.prepared_by, self.prepared_by)
def testDashboardSlug(self):
self.assertEqual(self.dashboard.slug, self.slug)
def testDashboardSlugClash(self):
# Create another dashboard with exactly the same name.
self.dashboard2 = Dashboard(name='Test Dashboard')
self.dashboard2.save()
self.assertEqual(self.dashboard2.slug, 'test-dashboard1')
And the traceback:
Installing json fixture 'initial_data' from '/Users/Eric/Documents/DjangoProjects/MMR/../MMR/dashboard/fixtures'.
Problem installing fixture '/Users/Eric/Documents/DjangoProjects/MMR/../MMR/dashboard/fixtures/initial_data.json': Traceback (most recent call last):
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/core/management/commands/loaddata.py", line 169, in handle
obj.save(using=using)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/core/serializers/base.py", line 165, in save
models.Model.save_base(self.object, using=using, raw=True)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/db/models/base.py", line 501, in save_base
rows = manager.using(using).filter(pk=pk_val)._update(values)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/db/models/query.py", line 491, in _update
return query.get_compiler(self.db).execute_sql(None)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/db/models/sql/compiler.py", line 861, in execute_sql
cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/db/models/sql/compiler.py", line 727, in execute_sql
cursor.execute(sql, params)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django/db/backends/mysql/base.py", line 86, in execute
return self.cursor.execute(query, args)
File "build/bdist.macosx-10.5-i386/egg/MySQLdb/cursors.py", line 174, in execute
self.errorhandler(self, exc, value)
File "build/bdist.macosx-10.5-i386/egg/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
IntegrityError: (1062, "Duplicate entry 'dashboard-action' for key 'app_label'")
The database is only created once – at the beginning of the test run. That is, when you execute
./manage.py test. Test fixtures are loaded and removed respectively before and after executing each test method. This means that all of your fixtures are loaded to the database before each test method is executed. The database is dropped after all tests have been run.Without seeing the code the first place I would check would be
initial_dataif it exists.Initial_datais loaded to the database at the end ofsyncdband this happens before testing starts. Make sure that yourinitial_datadoes not load any conflicting data.Second place to look would be other fixtures, especially if you are using more than one fixture file per test class.
Update
It seems that the error occurs even before the fixture (
initial.json) is loaded. There is most likely something insideinitial_data.jsonthat is duplicated and thereby violates database integrity.This is how I’d go about troubleshooting:
app_labelinitial_data.jsonand find out if there exist two rows with the same value forapp_label.On a side note I would suggest renaming the test fixture to something else. It is easy to get confused between
initial.jsonandinitial_data.json. Unless you meant to useinitial_data.jsonof course. In that case thefixtures = ...line is redundant and can be removed asinitial_data.jsonwill be loaded anyway.Update 2
After smugly giving advice and patting myself on the back I came upon this Django bug. I am digging up more dirt on it. Will update again after I find more.