我有一个 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/