如何在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
相关产品推荐
相关产品推荐

