【发布时间】:2019-04-10 13:35:37
【问题描述】:
我正在将一个大型 web 应用程序从 Python 2.7 移植到 Python 3.6。我已经管理了数据库迁移并使用 2to3 转换了代码,但是我在运行我的测试套件时遇到了问题。对于大量测试,我得到如下错误:
62 self = <django.db.backends.utils.CursorWrapper object at 0x7fc7d0abbeb8>
63 sql = 'SET CONSTRAINTS ALL IMMEDIATE', params = None
64
65 def execute(self, sql, params=None):
66 self.db.validate_no_broken_transaction()
67 with self.db.wrap_database_errors:
68 if params is None:
69 > return self.cursor.execute(sql)
70 E psycopg2.IntegrityError: insert or update on table "probex_historicalproject" violates forei
gn key constraint "probex_historicalpro_history_user_id_88371c5c_fk_auth_user"
71 E DETAIL: Key (history_user_id)=(303) is not present in table "auth_user".
72
73 ../../venv3/lib/python3.6/site-packages/django/db/backends/utils.py:62: IntegrityError
74
75 The above exception was the direct cause of the following exception:
76
77 self = <django.test.testcases.TestCase testMethod=__init__>
78
79 def _post_teardown(self):
80 """Performs any post-test things. This includes:
81
82 * Flushing the contents of the database, to leave a clean slate. If
83 the class has an 'available_apps' attribute, post_migrate isn't fired.
84 * Force-closing the connection, so the next test gets a clean cursor.
85 """
86 try:
87 > self._fixture_teardown()
88
89 ../../venv3/lib/python3.6/site-packages/django/test/testcases.py:925:
90 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
91 ../../venv3/lib/python3.6/site-packages/django/test/testcases.py:1081: in _fixture_teardown
92 connections[db_name].check_constraints()
93 ../../venv3/lib/python3.6/site-packages/django/db/backends/postgresql/base.py:243: in check_constraints
94 self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE')
95 ../../venv3/lib/python3.6/site-packages/raven/contrib/django/client.py:127: in execute
96 return real_execute(self, sql, params)
97 ../../venv3/lib/python3.6/site-packages/django/db/backends/utils.py:64: in execute
98 return self.cursor.execute(sql, params)
99 ../../venv3/lib/python3.6/site-packages/django/db/utils.py:94: in __exit__
100 six.reraise(dj_exc_type, dj_exc_value, traceback)
101 ../../venv3/lib/python3.6/site-packages/django/utils/six.py:685: in reraise
102 raise value.with_traceback(tb)
103 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
我尝试在我同事的一些机器上运行测试,有些人运行测试没有问题,但有些人和我有同样的问题。
另外值得注意的是:如果我自己运行单个测试文件(即py.test /path/to/file),则不会发生此错误。我认为这一定与测试之间处理数据库数据的方式有关。
这是一个失败的示例测试:
1
2 from django.utils import timezone
3 from tests.tests_probex.tests_python.testing_utilities import LoggedInTestCase
4 from tests.tests_probex.tests_python.factories import JobFactory
5 from probex.models import Profile, Tenant, Job
6 from probex.views.reports import build_tenant_report
7 from django.contrib.auth.models import User
8 import pytest
9
10 pytestmark = pytest.mark.xfail(reason="Not working in Python 3.6")
11
12
13 class TestTenantReport(LoggedInTestCase):
14 def setUp(self):
15 super(TestTenantReport, self).setUp()
16 self.end_date = timezone.now()
17 self.delta = timezone.timedelta(days=7)
18 self.start_date = self.end_date - self.delta
19
20 self.date = timezone.now() - timezone.timedelta(days=3)
21 self.job = JobFactory(absolute_num=1600, relative_num=1600, protocol=self.protocol, project=self.project, status='Co
mplete', created=self.date, submitter_id=self.user.id)
22
23 def test_returns_new_users(self):
24 users = User.objects.all()
25 for user in users:
26 user.date_joined = self.date
27 p = Profile.objects.get(user_id=user.id)
28 tenant = Tenant.objects.get(id=p.tenant_id)
29 tenant.app_scientist = self.user
30 user.save()
31 tenant.save()
32
33 report = build_tenant_report(self.user)
34 self.assertGreaterEqual(report['new_users'].count(), users.count())
LoggedInTestCase 是 django TestCase 的子类:
15 class LoggedInTestCase(TestCase):
16 def setUp(self):
17 self.user = User.objects.create_user(username='dummy@hotmail.com', email='dummy@hotmail.com', password="secret123")
18 self.user.user_permissions.add(Permission.objects.get(codename='add_job'))
19 self.user.user_permissions.add(Permission.objects.get(codename='change_job'))
20 self.user.user_permissions.add(Permission.objects.get(codename='add_project'))
21 self.user.user_permissions.add(Permission.objects.get(codename='add_user'))
22 self.user.user_permissions.add(Permission.objects.get(codename='change_user'))
23 self.tenant = Tenant.objects.create(name="testtenant")
24 self.user.profile.tenant = self.tenant
25 self.user.profile.save()
26 self.project = ProjectFactory(name="testproject", tenant=self.tenant, active=True, identifier='AAA')
27 self.protocol = ProtocolFactory()
28 self.root_term = TermFactory(is_root=True, acc='all')
29 self.login()
30
31 def login(self):
32 self.client.login(username='dummy@hotmail.com', password='secret123')
33
34 def logout(self):
35 self.client.logout()
36
37 def get_user(self):
38 return self.client
39
40 def permission_restricted(self, response, first_stop_url):
41 first_redirect, status_1 = response.redirect_chain[0]
42 second_redirect, status_2 = response.redirect_chain[1]
43 self.assertEqual(first_redirect, first_stop_url)
44 self.assertEqual(status_1, 302)
45 self.assertEqual(second_redirect, reverse('home'))
46 self.assertEqual(status_2, 302)
这些测试通常在 Python 2.7 下运行时通过,除了更新到 3.6 之外,我没有太大变化。我仍然希望他们现在通过。如果有人有任何指示,我将不胜感激。第一次在这里发布海报。
【问题讨论】:
-
我们能看到
LoggedInTestCase吗? -
@Franey 是的,我已经在上面添加了 LoggedInTestCase 的详细信息
标签: django python-3.x pytest