gpt4 book ai didi

python - 如何用自定义字符串完全替换 pytest 输出以进行测试?

转载 作者:太空宇宙 更新时间:2023-11-03 11:58:57 24 4
gpt4 key购买 nike

场景

我正在编写一个包,它要求我从通过 subprocess 运行的 pytest 中外部调用 pytest。很明显,从子进程捕获的输出正是我想要显示的错误,因为它具有 pytest 提供的所有良好格式和信息。不幸的是,目前主要的 pytest 调用只显示我的包装器的内部代码,而不是漂亮的子进程输出,在我打印它之后,它只显示在 pytest 的捕获标准输出部分中。我想格式化失败和错误的输出,就像直接调用代码一样,并隐藏进行了子进程调用。因此,我基本上想用不同的字符串完全替换一个测试函数的输出。这可能吗?

MWE

让我们看一下简单包装函数的 MWE(没有做任何有用的事情,但我能想到的最短的 MWE):

import functools
from subprocess import Popen, PIPE
import sys


def call_something(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
# for the sake of simplicity, a dummy call
p = Popen([sys.executable, '-c', 'import numby'], stderr=PIPE, stdout=PIPE)
# let's imagine this is the perfect string output we want
# to print instead of the actual output generated from...
error = p.communicate()[1].decode("utf-8")

if p.returncode != 0:
# ... this line
raise AssertionError(f'{error}')

return wrapper

@call_something
def test_something():
assert 1 == 2

如您所见,我的 test_something() 函数在子进程中会失败。

当前输出

如果我用这个文件运行 pytest,我会得到:

================================== FAILURES ===================================
_______________________________ test_something ________________________________

func = <function test_something at 0x000001EA414F1400>, args = (), kwargs = {}
p = <subprocess.Popen object at 0x000001EA414A67B8>
error = 'Traceback (most recent call last):\r\n File "<string>", line 1, in <module>\r\nModuleNotFoundError: No module named \'numby\'\r\n'

def wrapper(*args, **kwargs):
# for the sake of simplicity, a dummy call
p = Popen([sys.executable, '-c', 'import numby'], stderr=PIPE, stdout=PIPE)
# let's imagine this is the perfect string output we want
# to print instead of the actual output generated from...
error = p.communicate()[1].decode("utf-8")

if p.returncode != 0:
# ... this line
> raise AssertionError(f'{error}')
E AssertionError: Traceback (most recent call last):
E File "<string>", line 1, in <module>
E ModuleNotFoundError: No module named 'numby'

test_me.py:18: AssertionError
========================== 1 failed in 0.18 seconds ===========================

显然,我不想展示包装函数的细节。相反

期望的输出

我想展示子流程中发生的事情。所以它应该看起来像这样(或类似的)。

================================== FAILURES ===================================
_______________________________ test_something ________________________________

<string captured from subprocess>
========================== 1 failed in 0.11 seconds ===========================

所以我的问题更小:

问题简述

  • 如何用自定义字符串替换用于测试的 pytest 输出来 self 的 wrapper ?

最佳答案

引发错误时,您可以使用 from 语法来抑制或更改异常链接的方式。例如,请考虑以下内容:

try:
a / b
except ZeroDivisionError:
raise ValueError('Invalid b value')

这将显示一个 ZeroDivisionError,如果 b == 0 后跟一个 ValueError,但您可能想要抑制 ZeroDivisionError,因为唯一相关的部分是 ValueError。所以你应该写:

try:
a / b
except ZeroDivisionError:
raise ValueError('Invalid b value') from None

这只会显示ValueError,告诉你b是错误的

使用 from 语法还可以做其他事情,这与此处相关,请参阅 this thread了解详情。

我通过抑制奇怪的管道错误而不是引发 ModuleNotFoundError 来做一些与您正在尝试的非常相似的事情:

# Test if <module> is callable
try:
sp.run('<run some module>', shell=True, check=True, stdout=sp.PIPE)
except sp.CalledProcessError as exc:
raise ModuleNotFoundError(
'<some module> not working. Please ensure it is installed and can be called with the command: <command>'
) from exc

注意这里使用了 from exc

关于python - 如何用自定义字符串完全替换 pytest 输出以进行测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54640470/

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