py.test stacktraces目前看起来像这样:
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
模块中的行,对我的人眼来说会容易得多。
示例:
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
,但这不会这样做。
更新
首选没有unix管道的解决方案(如py.test ...| grep
)。
答案 0 :(得分:7)
看起来你正在调用pytest,如:
py.test --tb=native
此表单将输出派生自traceback.format_exception
的python stdlib堆栈跟踪使用pytest,您可以向项目添加conftest.py个文件。在这里,您可以添加任何代码来修改pytest行为。
小心!在以下两种方法中,使用人员monkey patching的may consider evil。
这是最简单的方法,但如果您要搜索的字符串出现在您不想隐藏的行中,则可能会出现问题。
这种方法修补py包中的ReprEntryNative类,这是pytest的依赖。
将以下代码放入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
如果字符串匹配对你来说不够真实,我们可以在它被转储到字符串之前检查回溯,并且只输出不是来自一组模块的帧。
这种方法修补了traceback.extract_tb函数,该函数可能会杀死小狗。
将以下代码放入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
答案 1 :(得分:2)
尝试使用倒置图案将输出连接到grep。这将打印除模式匹配的所有行。
python all_tests.py | grep -v "usr/lib64/python2.7/unittest"
答案 2 :(得分:1)
如果您知道使用的是什么操作系统并且不关心目录拆分,则可以删除导入操作系统并将os.sep替换为适当的分隔符
这将删除unittest模块所在位置及其后面的所有回溯。
import os
import sys
import unittest
class Stderr(object):
def __init__(self):
self.unittest_location = (os.sep).join(unittest.__file__.split(os.sep)[:-1])
self.stderr = sys.__stderr__
self.skip = False
def write(self, text):
if self.skip and text.find("\n") != -1: self.skip=False
elif self.skip: pass
else:
self.skip = text.find(self.unittest_location) != -1
if not self.skip: self.stderr.write(text)
sys.stderr = Stderr()
答案 3 :(得分:1)
全部归功于https://stackoverflow.com/a/24679193/59412
我只是冒昧地将其移植到最新的 pytest(撰写本文时为 6.2.3)。将其粘贴在您的 conftest.py
中。 (虽然不适用于 unittest
代码...因为它不在 site-packages
中)
选项 1:
(默认过滤所有 pip 安装的包)
# 5c4048fc-ccf1-44ab-a683-78a29c1a98a6
import _pytest._code.code
def test_skip_line(line):
"""
decide which lines to skip
"""
return 'site-packages' in line
class PatchedReprEntryNative(_pytest._code.code.ReprEntryNative):
def __init__(self, tblines):
self.lines = []
while len(tblines) > 0:
# [...yourfilter...]/test_thing.py", line 1, in test_thing
line = tblines.pop(0)
if test_skip_line(line):
# some line of framework code you don't want to see either...
tblines.pop(0)
else:
self.lines.append(line)
_pytest._code.code.ReprEntryNative = PatchedReprEntryNative
del _pytest._code.code
仅适用于 --tb=native
。就像我移植到这个版本的答案一样。
选项 2:
待定