繁体   English   中英

Pytest:如何盲目运行任何子进程并捕获所有 output?

[英]Pytest: How can I blindly run any subprocess and capture all output?

我有一个 Python 程序,它调用print()和/或调用 subprocess.Popen subprocess.Popen()对其他几种语言的脚本,它也可以print, console.log, system.out.println,等。实际的程序很容易打印所有this 到终端,这是预期的行为。

对于集成测试,我想捕获所有这些 output 以检查它是否与预期值匹配。 无法模拟子流程。 不是单元测试,我不在乎我的 Python 代码实际上在做什么,只是 output 是正确的。

所有这些选项都适用于捕获内部 Python output:

代码大致如下。 对于capfdredirect_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"]

这些都完美地获得了内部 output ,但都无法从 subprocess.Popen 获得一致的subprocess.Popen 我尝试使用所有这些方法,将subprocess.stdout设置为文件,设置为PIPE并稍后将其打印出来, shell=True和其他一些东西,但它们都有相同的奇怪问题。 我真的对这种行为没有任何解释,所以我只是希望有人能帮助我:

  • 当我使用它的 CLI 实际运行我的代码时,所有这些代码都可以正常工作。
  • JavaScript 子进程始终有效,无论我使用哪种方法,它的 output 都被正确捕获。
  • Python 子进程在我使用 VSCode 集成测试调试时确实有效,但当从命令行运行pytest时则无效。 嗯? 为什么?????!?
  • Lua 子进程完全挂起。 子进程似乎从未真正开始,尽管很难判断发生了什么,因为我无法从 Python 调试到 Lua,而且我不能只打印出来,因为 Z526EE8CFA9941CA85AZAC589E36 正在尝试捕获所有内容。
  • 到目前为止,我只添加了这 3 种语言,但我打算添加更多(理论上,所有这些),所以我希望有一个通用的解决方案。

我也可以尝试测试整个 CLI,但我想避免这种情况,而且我不确定它是否能正常工作。 如果有人知道如何强制 Pytest 像本机代码一样运行而不将子进程放在某种盒子中,那真的是我需要的。

对于那些想知道的人,我最终选择了capfd钩子,并完全删除了嵌套的子进程要求。 我的应用程序需要执行的子进程不再允许output 直接到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"]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM