我发现在一个简单的失败的单元测试中获得如此多的细节有点恼人。是否可以抑制除了实际定义的断言消息之外的所有内容?
Creating test database for alias 'default'...
.F
======================================================================
FAIL: test_get_sales_item_for_company (my_app.tests.SalesItemModelTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/kave/projects/my/my_app/tests.py", line 61, in test_get_sales_item_for_company
self.assertEqual(sales_items.count(), 1, 'Expected one sales item for this company, but got %s' % sales_items.count())
AssertionError: Expected one sales item for this company, but got 2
----------------------------------------------------------------------
Ran 2 tests in 0.313s
FAILED (failures=1)
Destroying test database for alias 'default'...
我觉得这不必要了。我需要知道失败的测试名称(方法)和断言消息。真的不需要追溯..
Traceback (most recent call last):
File "/home/kave/projects/my/my_app/tests.py", line 61, in test_get_sales_item_for_company
self.assertEqual(sales_items.count(), 1, 'Expected one sales item for this company, but got %s' % sales_items.count())
答案 0 :(得分:1)
猴子修补救援。你可以通过继承Django的TestCase来解决失败的追溯问题,而无需触及你的Django安装,如下所示:
import types
from django.utils.unittest.result import failfast
from django.test import TestCase
@failfast
def addFailureSansTraceback(self, test, err):
err_sans_tb = (err[0], err[1], None)
self.failures.append((test, self._exc_info_to_string(err_sans_tb, test)))
self._mirrorOutput = True
class NoTraceTestCase(TestCase):
def run(self, result=None):
result.addFailure = types.MethodType(addFailureSansTraceback, result)
super(NoTraceTestCase, self).run(result)
现在只需将您的测试用例设为NoTraceTestCase
而不是TestCase
的子类,您就可以了。不再追溯失败。 (注意异常仍然会打印回溯。如果你愿意的话,你可以将这些异常修补。)
以下是它的工作原理(感谢Jason Pratt for the quick lesson on monkey patching):
Django的测试运行器为每次测试运行调用TestCase的run
方法。 result
参数是django.utils.unittest.result.TestResult
类的一个实例,它处理向用户显示测试结果。每当测试失败时,run
都会拨打以下电话:result.addFailure(self, sys.exc_info())
。这就是回溯的来源 - 作为sys.exc_info()
返回的元组中的第三项。
现在,只需使用原始代码的副本覆盖run
并根据需要进行调整即可。但是run
方法是一个很好的75行长,所有需要改变的是一行,并且无论如何为什么错过了使用猴子修补的乐趣的机会?
result.addFailure
赋值将addFailure
对象中传递给NoTraceTestCase的result
方法的run
方法更改为新定义的addFailureSansTraceback
函数 - 首先使用result
转换为与types.MethodType
- 对象兼容的方法。
super
调用调用Django现有的TestCase run
。现在,当现有代码运行时,对addFailure
的调用实际上会调用新版本,即addFailureSansTraceback
。
addFailureSansTraceback
执行addFailure
的原始版本所做的事情 - 复制两行代码 - 除了添加一行用None
替换回溯(分配)到下一行代替err_sans_tb
的{{1}}。就是这样。
请注意,原始err
有一个addFailure
装饰器,因此会导入并使用它。说实话,我还没看过它的作用!
免责声明:我没有彻底研究过Django的测试代码。这只是一个快速的补丁,让它在常见的情况下工作。使用风险自负!