【发布时间】:2019-07-05 12:46:45
【问题描述】:
场景
我正在编写一个包,它要求我从通过subprocess 运行的pytest 内部调用pytest。所以很明显,从子进程捕获的输出正是我想要显示的错误,因为它具有 pytest 提供的所有很好的格式和信息。不幸的是,目前主要的 pytest 调用只显示我的包装器的内部代码,而不是漂亮的子进程输出,在我打印它之后,它只显示在 pytest 的捕获的 stdout 部分中。
我想格式化失败和错误的输出,就像直接调用代码一样,并隐藏进行了子进程调用。因此,我基本上想用不同的字符串完全替换一个测试函数的输出。这可能吗?
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 输出 来自我的包装?
【问题讨论】:
-
您找到解决问题的方法了吗?
-
很遗憾没有:(
标签: python subprocess pytest