gpt4 book ai didi

Django:如何在单元测试中隐藏 Traceback 以提高可读性?

转载 作者:行者123 更新时间:2023-12-01 05:29:41 24 4
gpt4 key购买 nike

我发现为一个简单的失败的单元测试获取如此多的细节有点烦人。除了实际定义的断言消息之外,是否可以抑制所有内容?

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())

最佳答案

猴子修补救援。您可以通过子类化 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 result 中的方法传递给 NoTraceTestCase 的 run 的对象新定义的 addFailureSansTraceback 方法函数——首先转换为 result - 与 types.MethodType 的对象兼容方法.
  • super call 调用 Django 现有的 TestCase run .现在,当现有代码运行时,调用 addFailure实际上会调用新版本,即 addFailureSansTraceback .
  • addFailureSansTraceback addFailure 的原始版本做了什么确实 -- 复制了两行代码 -- 除了添加一行用 None 替换回溯(对 err_sans_tb 的赋值,用于代替下一行中的 err)。就是这样。
  • 注意原文addFailure有一个 failfast装饰器,以便导入和使用。老实说,我没有看过它的作用!

  • 免责声明:我没有彻底研究过 Django 的测试代码。这只是让它在常见情况下工作的快速补丁。使用风险自负!

    关于Django:如何在单元测试中隐藏 Traceback 以提高可读性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11908784/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com