【发布时间】:2016-05-12 01:33:05
【问题描述】:
我有一个测试用例,我想通过从数据库中获取数据来检查用于分配房间的匈牙利算法。因此,我在setUp 方法中创建了一些对象来填充一些数据。但是,在执行测试时,它们会失败(本质上,setUp 失败)并带有以下堆栈跟踪:
======================================================================
ERROR: test_hungarian_on_users (allocation.tests.TestHungarian)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/parthshukla/roomer/allocation/tests.py", line 68, in setUp
code='MA-302'
File "/Users/parthshukla/roomer/venv/lib/python2.7/site-packages/django/db/models/manager.py", line 122, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/parthshukla/roomer/venv/lib/python2.7/site-packages/django/db/models/query.py", line 401, in create
obj.save(force_insert=True, using=self.db)
File "/Users/parthshukla/roomer/roomer/models.py", line 297, in save
super(Room, self).save(kwargs)
File "/Users/parthshukla/roomer/venv/lib/python2.7/site-packages/django/db/models/base.py", line 708, in save
force_update=force_update, update_fields=update_fields)
File "/Users/parthshukla/roomer/venv/lib/python2.7/site-packages/django/db/models/base.py", line 736, in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/Users/parthshukla/roomer/venv/lib/python2.7/site-packages/django/db/models/base.py", line 820, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/Users/parthshukla/roomer/venv/lib/python2.7/site-packages/django/db/models/base.py", line 859, in _do_insert
using=using, raw=raw)
File "/Users/parthshukla/roomer/venv/lib/python2.7/site-packages/django/db/models/manager.py", line 122, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/parthshukla/roomer/venv/lib/python2.7/site-packages/django/db/models/query.py", line 1039, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "/Users/parthshukla/roomer/venv/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 1060, in execute_sql
cursor.execute(sql, params)
File "/Users/parthshukla/roomer/venv/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/Users/parthshukla/roomer/venv/lib/python2.7/site-packages/django/db/utils.py", line 95, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/Users/parthshukla/roomer/venv/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/Users/parthshukla/roomer/venv/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 323, in execute
return Database.Cursor.execute(self, query, params)
IntegrityError: UNIQUE constraint failed: roomer_room.id
----------------------------------------------------------------------
该错误似乎源于 roomer_room.id(django 生成的 UUID)的完整性约束,这表明存在具有该 ID 的现有房间。但是,在错误源自的第 68 行(第一次调用 Room.objects.create())之前的 Room.objects.all() 返回一个空数组。因此,Room 表中没有其他有意义的对象,因为 django 测试会在生成测试用例时创建一个新数据库,并在拆卸时将其销毁。这是供参考的测试用例。
class TestHungarian(TestCase):
def setUp(self):
self.basic_cost_matrix = [[82, 83, 69, 92], [77, 37, 49, 92], [11, 69, 5, 86], [8, 9, 98, 23]]
self.basic_hungarian_result = [69, 37, 11, 23]
# Basically Leo
UserProfile.objects.create(
username='a',
seniority=2,
year=17,
major='Computer Science',
country='Germany',
old_college='NM',
college='ME',
)
# Basically Sid
UserProfile.objects.create(
username='b',
seniority=3,
year=16,
major='Computer Science',
country='India',
old_college='ME',
college='ME',
)
# Basically a mover
UserProfile.objects.create(
username='c',
seniority=1,
year=18,
major='Physics',
country='Albania',
old_college='NM',
college='ME',
)
# Basically a Nordie freshie
UserProfile.objects.create(
username='d',
seniority=1,
year=18,
major='Chemistry',
country='Albania',
old_college='NM',
college='NM',
)
user_a = UserProfile.objects.get(username='a')
user_b = UserProfile.objects.get(username='b')
user_c = UserProfile.objects.get(username='c')
user_d = UserProfile.objects.get(username='d')
# user_a.send_roommate_request(user_b)
# user_b.inbox.first().accept()
Room.objects.create(
college='ME',
floor=3,
block='A',
code='MA-302'
)
Room.objects.create(
college='ME',
floor=2,
block='A',
code='MA-203'
)
Room.objects.create(
college='ME',
floor=3,
block='C',
code='MC-104'
)
Room.objects.create(
college='NM',
floor=3,
block='B',
code='NB-351'
)
Room.objects.create(
college='NM',
floor=3,
block='B',
code='NA-350'
)
room_a = Room.objects.get(code='MA-302')
room_b = Room.objects.get(code='MA-203')
room_c = Room.objects.get(code='NB-351')
room_d = Room.objects.get(code='MC-104')
room_e = Room.objects.get(code='NA-350')
# room_a.associated.add(room_b)
UserPreference.objects.create(
preference_level=1,
user=user_a,
room=room_b
)
UserPreference.objects.create(
preference_level=2,
user=user_a,
room=room_d
)
UserPreference.objects.create(
preference_level=1,
user=user_b,
room=room_a
)
UserPreference.objects.create(
preference_level=2,
user=user_b,
room=room_d
)
UserPreference.objects.create(
preference_level=1,
user=user_c,
room=room_d
)
UserPreference.objects.create(
preference_level=2,
user=user_c,
room=room_a
)
UserPreference.objects.create(
preference_level=1,
user=user_d,
room=room_c
)
UserPreference.objects.create(
preference_level=2,
user=user_d,
room=room_e
)
self.pref_a = UserPreference.objects.get(user=user_a, preference_level=1)
self.pref_b = UserPreference.objects.get(user=user_b, preference_level=1)
self.pref_c = UserPreference.objects.get(user=user_c, preference_level=1)
self.pref_d = UserPreference.objects.get(user=user_d, preference_level=1)
def test_basic_hungarian(self):
result = get_cost_matrix(self.basic_cost_matrix)
self.assertEqual(result, self.basic_hungarian_result)
def test_hungarian_on_users(self):
allocations = get_hungarian()
self.assertEqual(get_dict_from_key_in_list("user", "sshukla", allocations)["preference"], self.pref_b.preference_level)
【问题讨论】:
-
你认为
IntegrityError: UNIQUE constraint failed: roomer_room.id可能意味着什么? -
@JohnMee 好吧,通常它应该是指对象存在于数据库中的事实,因为 roomer_room.id(django 生成的 UUID)已经在数据库中的某个表上。但是,django 测试会在设置和拆卸时创建和销毁数据库。所以,这对我来说没有任何意义。
-
错误信息告诉我们有两个roomer_room试图使用同一个id。去寻找那个。可能在 68 号线附近。
-
@JohnMee 第 68 行是 setUp 方法中对 Room.objects.create 的第一次调用。没有重复,这使整个错误变得非常混乱。 ://
-
你怎么知道没有重复?