python - 如何使用子进程有效地测试基于 readline 的 Python 程序?

标签 python unit-testing python-3.x subprocess readline

我有一个 Python 程序,在某些条件下,它应该提示用户输入文件名。但是,我想提供一个默认文件名,用户可以根据需要进行编辑。 这通常意味着他们需要按退格键来删除当前文件名并将其替换为他们喜欢的文件名。

为此,我改编了 this answer对于 Python 3,进入:

def rlinput(prompt, prefill=''):
    readline.set_startup_hook(lambda: readline.insert_text(prefill))
    try:
        return input(prompt)
    finally:
        readline.set_startup_hook()

new_filename = rlinput("What filename do you want?", "foo.txt")

当程序按预期交互运行时,这将按预期工作 - 退格并输入新文件名后,new_filename 包含 bar.txt 或用户输入的任何文件名。

但是,我还想使用单元测试来测试程序。一般来说,为了做到这一点,我将程序作为子进程运行,以便我可以将其输入提供给标准输入(从而在用户使用它时对其进行测试)。我有一些单元测试代码(简化的)如下所示:

p = Popen(['mypythonutility', 'some', 'arguments'], stdin=PIPE)
p.communicate('\b\b\bbar.txt')

我的意图是,这应该模拟用户在提供的 foo.txt 上“退格”,然后输入 bar.txt

但是,这似乎并没有达到预期的效果。相反,经过一些调试后,我的程序中的 new_filename 最终会出现与 \b\b\bbar.txt 等效的内容。我期待的只是 bar.txt

我做错了什么?

最佳答案

从 Python 控制交互式子进程的适当方法是使用 pexpect模块。该模块使子进程相信它正在交互式终端 session 中运行,并让父进程准确确定将哪些击键发送到子进程。

Pexpect is a pure Python module for spawning child applications; controlling them; and responding to expected patterns in their output. Pexpect works like Don Libes’ Expect. Pexpect allows your script to spawn a child application and control it as if a human were typing commands.

关于python - 如何使用子进程有效地测试基于 readline 的 Python 程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30227378/

相关文章:

python-3.x - 尝试使用 GEKKO OPTIMIZER 时出现 "No loop matching the specified signature and casting was found for ufunc solve"

Python/Django 测试运行程序导入错误

python - 写入 CSV

python - 涉及 Python float(sys.argv[1]) 的未知代码错误

asp.net-mvc - 如何对我的 asp.net-mvc Controller 的 OnActionExecuting 方法进行单元测试?

perl - 外部程序的假 CGI 环境

python - Plotly:如何对 Pandas 数据框使用下拉菜单?

python - Pyml得到的分类器如何使用

unit-testing - 持续集成(Hudson/Jenkins)和R编程

python - 为什么在 Pandas 数据框中使用 Z-score 进行标准化会生成 NaN 列?