py.test:从 unittest 模块隐藏堆栈跟踪行 [英] py.test: hide stacktrace lines from unittest module

查看:25
本文介绍了py.test:从 unittest 模块隐藏堆栈跟踪行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

py.test 堆栈跟踪目前看起来像这样:

py.test stacktraces look like this at the moment:

Traceback (most recent call last):
  File "/home/foo_tbz_di476/src/djangotools/djangotools/tests/ReadonlyModelTestCommon.py", line 788, in test_stale_or_missing_content_types
    self.assertEqual([], errors, 'Stale/Missing ContentTypes: %s' % '\n'.join(errors))
  File "/usr/lib64/python2.7/unittest/case.py", line 511, in assertEqual
    assertion_func(first, second, msg=msg)
  File "/usr/lib64/python2.7/unittest/case.py", line 740, in assertListEqual
    self.assertSequenceEqual(list1, list2, msg, seq_type=list)
  File "/usr/lib64/python2.7/unittest/case.py", line 722, in assertSequenceEqual
    self.fail(msg)
  File "/usr/lib64/python2.7/unittest/case.py", line 408, in fail
    raise self.failureException(msg)

如果输出跳过 unittest 模块中的行,对我的人眼来说会容易得多.

It would be much easier for my human eyes if the output would skip the lines from the unittest module.

示例:

Traceback (most recent call last):
  File "/home/foo_tbz_di476/src/djangotools/djangotools/tests/ReadonlyModelTestCommon.py", line 788, in test_stale_or_missing_content_types
    self.assertEqual([], errors, 'Stale/Missing ContentTypes: %s' % '\n'.join(errors))

我尝试了选项 --tb=short 但这并没有做到这一点.

I tried option --tb=short but this does not do this.

更新

首选没有 unix 管道的解决方案(如 py.test ...| grep).

A solution without a unix pipe (like py.test ...| grep) is preferred.

推荐答案

看起来你正在调用 pytest 像:

It looks like you are invoking pytest like:

py.test --tb=native

此表单将输出一个派生自 traceback.format_exception 的 python stdlib stacktrace

This form will output a python stdlib stacktrace derived from traceback.format_exception

使用 pytest,您可以添加 conftest.py 文件到您的项目.您可以在此处添加任何代码来修改 pytest 行为.

With pytest you can add a conftest.py file(s) to your project. Here you can add any bits of code to modify pytest behaviour.

当心!在以下两种方法中都使用 monkey patching ,人们可能认为是邪恶的.

Beware! In both the following approaches use monkey patching which people may consider evil.

这是最简单的方法,但如果您要搜索的字符串出现在您不想隐藏的行中,则可能会出现问题.

This is the simplest approach but could be a problem if the string you are searching for appears in a line that you don't want to hide.

此方法修补了 py 包中的 ReprEntryNative 类,该类是 pytest 的依赖项.

This approach patches the ReprEntryNative class in the py package which is a dependancy of pytest.

将以下代码放入你的conftest.py

Put the following code in you conftest.py

import py

def test_skip_line(line):
    """decide which lines to skip, the code below will also skip the next line if this returns true"""
    return 'unittest' in line

class PatchedReprEntryNative(py._code.code.ReprEntryNative):
    def __init__(self, tblines):
        self.lines = []
        while len(tblines) > 0:
            line = tblines.pop(0)
            if test_skip_line(line):
                # skip this line and the next
                tblines.pop(0)
            else:
                self.lines.append(line)
py._code.code.ReprEntryNative = PatchedReprEntryNative

选项 2:回溯帧检查

如果字符串匹配对您来说不够真实,我们可以在它转储到字符串之前检查回溯,并且只输出不是来自一组模块的帧.

Option 2: traceback frame inspection

If string matching isnt true enough for you, we can inspect the traceback before it gets dumped to strings and only output frames that aren't from a set of modules.

这种方法修补了可能会杀死小狗的 traceback.extract_tb 函数.

This approach patches the traceback.extract_tb function which probably kills puppies.

将以下代码放入你的conftest.py

Put the following code in you conftest.py

import inspect
import linecache
import traceback
import unittest.case
import sys    

SKIPPED_MODULES = [
    unittest.case
]

def test_skip_frame(frame):
    module = inspect.getmodule(frame)
    return module in SKIPPED_MODULES

def tb_skipper(tb):
    tbnext = tb.tb_next
    while tbnext is not None:
        if test_skip_frame(tbnext.tb_frame):
            tbnext = tbnext.tb_next
        else:
            yield tbnext
    yield None

def new_extract_tb(tb, limit = None):
    if limit is None:
        if hasattr(sys, 'tracebacklimit'):
            limit = sys.tracebacklimit
    list = []
    n = 0
    new_tb_order = tb_skipper(tb) # <-- this line added
    while tb is not None and (limit is None or n < limit):
        f = tb.tb_frame
        lineno = tb.tb_lineno
        co = f.f_code
        filename = co.co_filename
        name = co.co_name
        linecache.checkcache(filename)
        line = linecache.getline(filename, lineno, f.f_globals)
        if line: line = line.strip()
        else: line = None
        list.append((filename, lineno, name, line))
        tb = next(new_tb_order) # <-- this line modified, was tb = tb.tb_next
        n = n+1
    return list
traceback.extract_tb = new_extract_tb

这篇关于py.test:从 unittest 模块隐藏堆栈跟踪行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆