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开发者_如何学Go 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'")
So, I am wondering, isn't the database supposed to be created and populated at the beginning of each TestCase
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.
I keep getting duplicate (IntegrityError) when it runs in the test suite
Without seeing the code the first place I would check would be initial_data
if it exists. Initial_data
is loaded to the database at the end of syncdb
and this happens before testing starts. Make sure that your initial_data
does 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
Problem installing fixture '/Users/Eric/Documents/DjangoProjects/MMR/../MMR/dashboard/fixtures/initial_data.json':
It seems that the error occurs even before the fixture (initial.json
) is loaded. There is most likely something inside initial_data.json
that is duplicated and thereby violates database integrity.
This is how I'd go about troubleshooting:
"Duplicate entry 'dashboard-action' for key 'app_label'"
- Identify which model/table has a constraint that matches
app_label
- Go through
initial_data.json
and find out if there exist two rows with the same value forapp_label
. - Remove one of them and try again.
On a side note I would suggest renaming the test fixture to something else. It is easy to get confused between initial.json
and initial_data.json
. Unless you meant to use initial_data.json
of course. In that case the fixtures = ...
line is redundant and can be removed as initial_data.json
will 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.
精彩评论