我们有一个包含大约 10,000 个 Django+Nose 单元测试的大型 Django 项目。我们很少在代码库中使用事务。可能我们 99% 的代码库不使用事务。该项目在 Django 1.5.8 和 Django Nose 1.4.1 上。(是的,我知道这已经很老了。我们目前正在进行一个更新到 Django 1.6 的项目 18 个月,但它还没有完成。所以,如果我的问题的解决方案是“升级 Django”,我我需要一种方法来修补它,因为这个问题现在正在发生,而且我们还需要几个月的时间才能完成 Django 的升级。)
我们今天遇到了一个以前从未见过的新错误。我们添加了一个新的数据库(和必要DATABASES['geo']
的设置),其中包含一个应用程序不会更新的大型静态数据集。它是一个只读数据库,恰好存在于 MySQL 中。与我们所有其他数据库一样,Django Nose 在每次测试运行的开始(结束)时开始创建新数据库的测试副本(并破坏所述测试数据库)。这导致了许多问题,包括磁盘空间问题和浪费时间的问题,但测试确实运行并通过了。
为了解决这个问题,我们添加'TEST_MIRROR': 'geo'
了DATABASES['geo']
设置。这就是这个头痛开始的地方。只是这种变化导致我们测试用例的一小部分随机部分在每次测试运行中失败:
<nose.suite.ContextSuite context=TestFacebookApiVersion>:setup
<nose.suite.ContextSuite context=RegisterPageTests>:setup
<nose.suite.ContextSuite context=CommonCeleryTasks>:setup
<nose.suite.ContextSuite context=CommonCeleryTestTasks>:setup
<nose.suite.ContextSuite context=S3PublishTestCase>:setup
<nose.suite.ContextSuite context=TestCEP>:setup
<nose.suite.ContextSuite context=AdbInvitesJsonTests>:setup
每个测试用例的错误和堆栈跟踪都是相同的:
Transaction managed block ended with pending COMMIT/ROLLBACK
Traceback (most recent call last):
File "/var/lib/jenkins/workspace/my_workspace/my_project/lib/python2.7/site-packages/nose/suite.py", line 209, in run
self.setUp()
File "/var/lib/jenkins/workspace/my_workspace/my_project/lib/python2.7/site-packages/nose/suite.py", line 292, in setUp
self.setupContext(ancestor)
File "/var/lib/jenkins/workspace/my_workspace /my_project/lib/python2.7/site-packages/nose/suite.py", line 315, in setupContext
try_run(context, names)
File "/var/lib/jenkins/workspace/my_workspace/my_project/lib/python2.7/site-packages/nose/util.py", line 471, in try_run
return func()
File "/var/lib/jenkins/workspace/my_workspace/my_project/lib/python2.7/site-packages/django_nose/testcases.py", line 43, in setUpClass
if not test.testcases.connections_support_transactions():
File "/var/lib/jenkins/workspace/my_workspace /my_project/lib/python2.7/site-packages/django/test/testcases.py", line 827, in connections_support_transactions
for conn in connections.all())
File "/var/lib/jenkins/workspace/my_workspace/my_project/lib/python2.7/site-packages/django/test/testcases.py", line 827, in <genexpr>
for conn in connections.all())
File "/var/lib/jenkins/workspace/my_workspace/my_project/lib/python2.7/site-packages/django/utils/functional.py", line 45, in __get__
res = instance.__dict__[self.func.__name__] = self.func(instance)
File "/var/lib/jenkins/workspace/my_workspace/my_project/lib/python2.7/site-packages/django/db/backends/__init__.py", line 455, in supports_transactions
self.connection.leave_transaction_management()
File "/var/lib/jenkins/workspace/my_workspace/my_project/lib/python2.7/site-packages/django/db/backends/__init__.py", line 138, in leave_transaction_management
"Transaction managed block ended with pending COMMIT/ROLLBACK")
而且,更糟糕的是,少数失败的测试用例每次都不同。这是我第二次运行它时的失败:
<nose.suite.ContextSuite context=BaseTemplateContainerTests>:setup
<nose.suite.ContextSuite context=MessageServiceNotifierTests>:setup
<nose.suite.ContextSuite context=TestFormatShortAddress>:setup
<nose.suite.ContextSuite context=RevisionableTestCase>:setup
<nose.suite.ContextSuite context=TestSoaHelpers>:setup
<nose.suite.ContextSuite context=TestDateUtils>:setup
等等。
正如您从堆栈跟踪中看到的那样,执行甚至没有进入我们的源代码。在我们的测试用例开始执行之前,它在 Django Nose 源代码中失败了。而且,这只是我们测试的一小部分。其他 9,600 多个单元测试都以优异的成绩通过。
我不知道该怎么办。我不是故意创建任何事务,添加'TEST_MIRROR': 'geo'
到DATABASES['geo']
配置中会导致这个问题对我来说没有意义,但确实如此。
我怎样才能解决这个问题?