Тестирование интерактивных программ python

Я хотел бы знать, какие инструменты тестирования для python поддерживают тестирование интерактивных программ. Например, у меня есть приложение, запущенное:

$ python dummy_program.py 

>> Hi whats your name? Joseph

Я хотел бы использовать инструмент Joseph, чтобы я мог эмулировать это интерактивное поведение.

Ответ 1

Если вы тестируете интерактивную программу, рассмотрите возможность использования expect. Он разработан специально для взаимодействия с консольными программами (хотя больше для автоматизации задач, а не для тестирования).

Если вам не нравится, что ожидаемый язык основан на (tcl), вы можете попробовать pexpect, что также облегчает взаимодействие с консольной программой.

Ответ 2

Лучше всего, скорее всего, использовать инъекцию зависимостей, так что то, что вы обычно выбирали из sys.stdin(например), фактически является переданным объектом. Таким образом, вы можете сделать что-то вроде этого:

import sys

def myapp(stdin, stdout):
    print >> stdout, "Hi, what your name?"
    name = stdin.readline()
    print >> stdout "Hi,", name

# This might be in a separate test module
def test_myapp():
    mock_stdin = [create mock object that has .readline() method]
    mock_stdout = [create mock object that has .write() method]
    myapp(mock_stdin, mock_stdout)

if __name__ == '__main__':
    myapp(sys.stdin, sys.stdout)

К счастью, Python делает это довольно легко. Здесь более подробная ссылка для примера издевательского stdin: http://konryd.blogspot.com/2010/05/mockity-mock-mock-some-love-for-mock.html

Ответ 3

Хорошим примером может служить файл test_embed.py пакета IPython.

Там используются два разных подхода:

подпроцесс

import subprocess
# ...
subprocess.Popen(cmd, env=env, stdin=subprocess.PIPE,
                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate(_exit_cmd_string)

pexpect (как уже упоминалось Брайаном Окли

import pexpect
# ...
child = pexpect.spawn(sys.executable, ['-m', 'IPython', '--colors=nocolor'],
                          env=env)
# ...
child.sendline("some_command")
child.expect(ipy_prompt)