我正在编写一个程序包,要求我从通过pytest
运行的pytest
中外部调用subprocess
。因此,显然,从子流程捕获的输出正是我要显示的错误,因为它具有pytest提供的所有出色的格式和信息。不幸的是,当前主要的pytest调用仅显示包装器的内部代码,而不是漂亮的子进程输出,在我将其输出后,仅显示在pytest的捕获的stdout部分中。我想格式化输出以查找失败和错误,就像直接调用代码一样,并隐藏进行了子流程调用的过程。因此,我基本上想用一个不同的字符串完全替换一个测试函数的输出。这可能吗?
让我们看一下一个简单的包装函数的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中外部调用pytest。因此,显然从子流程中捕获的输出正是我想要的错误...
引发错误时,可以使用from
语法抑制或更改异常的链接方式。例如,考虑以下内容: