You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中测试指定Shell是否已被执行?

如何在不Mock的情况下测试Python函数是否调用指定Shell?

我想要测试一个执行Shell命令的Python函数,根据testfixtures文档有两种测试方式:一是执行真实进程并检查结果,二是Mock subprocess模块验证交互。

我的函数run_in_shell基于subprocess实现,但未显式依赖它,所以想做「真实」测试。函数代码如下:

import subprocess

def run_in_shell(command, shell_name=None):
    """Run command in default shell. Use named shell instead if given."""
    subprocess.run(command, shell=True, executable=shell_name)

我已经写了测试用例验证函数能通过默认Shell执行命令:

import pytest

def test_with_command_string(capfd):
    run_in_shell("echo 'hello'")
    cap = capfd.readouterr()
    assert cap.out.strip() == "hello"
    assert cap.err.strip() == ""

现在需要验证函数可以使用用户指定的Shell(比如/bin/bash)执行命令。调用run_in_shell("echo 'hello'", shell_name="/bin/bash")能正常输出hello,但怎么在不使用Mock的情况下证明它确实调用了/bin/bash?

我尝试用ptracer追踪系统调用,但输出不符合预期:看不到带有Shell名称的clone或fork调用,也看不懂read调用里的字符串,还没发现write调用。相关代码和输出如下:

追踪代码:

def callback(syscall):
    name = syscall.name
    args = ",".join([str(a.value) for a in syscall.args])
    print(f"{name}({args})")

with ptracer.context(callback):
    run_in_shell("echo 'hello'")

with ptracer.context(callback):
    run_in_shell("echo 'hello'", shell_name="/bin/bash")

输出结果:

hello
pipe2((23, 24),524288)
clone(18874385,0,None,261939,0)
close(24)
read(23,bytearray(b'U\r\r\n'),50000)
close(23)
wait4(262130,0,0,None)

hello
pipe2((24, 25),524288)
clone(18874385,0,None,261939,0)
futex(2,129,1,0,9693984,9694016)
futex(0,129,1,0,None,9694016)
close(25)
read(24,bytearray(b'\x1d'),50000)
close(24)
wait4(262308,0,0,None)

我对系统调用的实际行为有误解,请问遗漏了什么?能不能通过Python和Pytest实现这个测试?如果不行,我会修改函数让它显式依赖subprocess函数,再用Mock验证交互。


内容的提问来源于stack exchange,提问作者Iain Samuel McLean Elder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 05:25:17