gpt4 book ai didi

python - 如何在unittest中捕获python子进程stdout

转载 作者:行者123 更新时间:2023-11-28 22:23:19 25 4
gpt4 key购买 nike

我正在尝试编写一个单元测试来执行一个写入标准输出的函数,捕获该输出并检查结果。有问题的函数是一个黑匣子:我们无法改变它的输出方式。出于本示例的目的,我对其进行了相当大的简化,但本质上该函数使用 subprocess.call() 生成其输出。

无论我尝试什么,我都无法捕获输出。它总是被写入屏幕,并且测试失败,因为它没有捕获任何内容。我尝试了 print() 和 os.system()。使用 print() 我可以捕获标准输出,但也不能使用 os.system()。

它也不特定于单元测试。我已经编写了没有相同结果的测试示例。

类似的问题已经问了很多,答案似乎都归结为使用 subprocess.Popen() 和 communicate() ,但这需要更改黑盒。我确定有一个我只是没有遇到的答案,但我很困惑。

我们正在使用 Python-2.7。

无论如何,我的示例代码是这样的:

#!/usr/bin/env python
from __future__ import print_function
import sys
sys.dont_write_bytecode = True

import os
import unittest
import subprocess
from contextlib import contextmanager
from cStringIO import StringIO

# from somwhere import my_function
def my_function(arg):
#print('my_function:', arg)
subprocess.call(['/bin/echo', 'my_function: ', arg], shell=False)
#os.system('echo my_function: ' + arg)

@contextmanager
def redirect_cm(new_stdout):
old_stdout = sys.stdout
sys.stdout = new_stdout
try:
yield
finally:
sys.stdout = old_stdout

class Test_something(unittest.TestCase):
def test(self):
fptr = StringIO()
with redirect_cm(fptr):
my_function("some_value")

self.assertEqual("my_function: some_value\n", fptr.getvalue())

if __name__ == '__main__':
unittest.main()

最佳答案

上面的代码有两个问题

  1. StringIO fptr当前进程和派生进程不共享,即使派生进程已将结果写入 StringIO,我们也无法在当前进程中获得结果对象

  2. Changing sys.stdout doesn’t affect the standard I/O streams os.popen() 执行的进程数, os.system()exec*() os 模块中的函数族

一个简单的解决方案是

  1. 使用 os.pipe在两个进程之间共享结果

  2. 使用 os.dup2而不是改变 sys.stdout

演示示例如下所示

import sys
import os
import subprocess
from contextlib import contextmanager


@contextmanager
def redirect_stdout(new_out):
old_stdout = os.dup(1)
try:
os.dup2(new_out, sys.stdout.fileno())
yield
finally:
os.dup2(old_stdout, 1)


def test():
reader, writer = os.pipe()

with redirect_stdout(writer):
subprocess.call(['/bin/echo', 'something happened what'], shell=False)

print os.read(reader, 1024)


test()

关于python - 如何在unittest中捕获python子进程stdout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47066063/

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