如何测试给定的 shell 是否已在 Python 中执行?

问题描述 投票:0回答:1

我想测试一个执行 shell 命令的 Python 函数。

根据testfixtures有两种方法:

  • 执行真实过程并检查结果
  • 模拟子流程模块检查预期的交互

我的函数称为

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

调用非常简单。这会将

hello
打印到终端。

run_in_shell("echo 'hello'", shell_name="/bin/bash")

在没有嘲笑的情况下,我如何表明它执行了

/bin/bash
来这样做?

我尝试使用 ptracer 来跟踪系统调用,但输出令我失望。

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")

我希望看到带有 shell 名称的

clone
fork
调用,但没有什么那么清楚。我不明白
read
调用中的字符串,也没有看到任何
write
调用。

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 进行测试是否可能且实用?如果没有,我将重新定义我的函数以显式依赖于子流程函数之一,然后我可以使用模拟来测试它是否向函数发送了正确的消息。

python linux pytest ptrace
1个回答
0
投票

如果我理解正确的话,对于此检查,我们要做的就是验证传入的任何 shell 是否正在使用。

我会尽可能简单,只打印活动 shell 的名称,然后验证它是否与目标 shell 匹配。类似的东西

def test_executes_in_specified_shell(capfd):
    target_shell = "/bin/bash" 
    
    print_current_shell = "ps -p $$ -oargs="
    run_in_shell(print_current_shell, shell_name=target_shell)

    current_shell = # Retrieve/parse capfd stdout
    assert current_shell == target_shell
    
© www.soinside.com 2019 - 2024. All rights reserved.