我有一个 Python 程序,它可以在其他几种语言的脚本上调用
print()
和/或调用 subprocess.Popen()
,也可以 print, console.log, system.out.println,
等。实际的程序可以轻松地将所有这些打印到终端,这是预期的行为.
对于集成测试,我想捕获所有这些输出以检查它是否与预期值匹配。我无法模拟子流程。这不是单元测试,我不关心我的Python代码实际上在做什么,只关心输出是否正确。
所有这些选项都可用于捕获内部 Python 输出:
capfd
固定装置直接通过 Pytest 捕获并读取所有输出
context_lib
和
redirect_stdout
sys.stdout
重新分配给显式文件,然后读取该文件以获取输出
capfd
和
redirect_stdout
,您只需改变
run_string
之前和之后所做的事情即可。
# tests are parametrized from several JSON files.
def test_code(test_json):
with open("/tmp/output_file.txt", "w+") as output_file:
orig_stdout = sys.stdout
sys.stdout = output_file
print("initial")
run_string(test_json["code"])
output_file.seek(0)
sys.stdout = orig_stdout
output = output_file.read()
assert output == test_json["expected"]
这些都完美地获得了内部输出,但都未能从subprocess.Popen
获得一致的输出。我尝试过使用所有这些方法,将
subprocess.stdout
设置为文件,设置为
PIPE
并稍后将其打印回来,
shell=True
以及其他一些方法,但它们都有相同的奇怪问题。我真的无法解释这种行为,所以我只是希望有人可以帮助我:
pytest
时,不。啊?为什么?!?!?!?
capfd
钩子,并完全删除了嵌套子流程的要求。我的应用程序需要执行的子进程不再允许直接输出到 shell,特别是因为它是如此不一致。这是我最终得到的代码。
def test_dits(dit_json, capfd):
if "long" in dit_json and not pytest.all_val: # type: ignore
pytest.skip("Long test")
run_string(dit_json["dit"], "tests/fail.dit")
output, err = capfd.readouterr()
assert output == dit_json["expected"]