0

I'm currently writing a module which uses console_script in setup.py to create scripts at installation time. For performing the tests I use the plugin pytest-console-scripts to execute those scripts. One of the functions I want to test involves a input() call to get an anwer from the user ('y'es or 'n'o). But I do not have any idea on how to mock this input.

A sample test using pytest-console-scripts looks like:

import pytest

def test_my_function(script_runner):
    # first option is the console script to be run followed by arguments
    ret = script_runner.run('myscript', '--version')
    assert ret.success

This can be used when the console script does not involve user action. How can this be solved?

Many thanks in advance, regards, Thomas

EDIT: the provided solutions in How to test a function with input call may solve my question only partially. My intention is to test the functionality through the console script, but not importing the module containing the function called through that script - if this is possible.

brillenheini
  • 793
  • 7
  • 22
  • Does this answer your question? [How to test a function with input call?](https://stackoverflow.com/questions/35851323/how-to-test-a-function-with-input-call) – Christopher Peisert Oct 16 '20 at 12:42
  • I already stumbled across that link, the solution requires the module to be installed. My intention is to test the module through the console script. However, it seems that I may have to load that function from the package and do the test that way. – brillenheini Oct 17 '20 at 04:15

1 Answers1

1

After investigating a lot more through Google I came across a solution, which worked perfectly for me:

# pip install pytest-mock pytest-console-scripts

...

def test_user_input(script_runner, mocker):
    # optional use side_effect with any kind of value you try to give to
    # your tested function
    mocker.patch('builtins.input', return_value='<your_expected_input>')
    # use side_effect=<values> instead if you want to insert more than one value

    # Options have to be seperated
    # Example: ('my_prog', '-a', 'val_a', '-b', 'val_b')
    #      or: ('my_prog', '-a val_a -b val_b'.split(' '))
    ret = script_runner.run('my_prog')
    assert ret.success
    assert ret.stdout == <whatever>
    # or assert 'string' in ret.stdout

See https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.side_effect for further possibilities of how to use side_effect.

brillenheini
  • 793
  • 7
  • 22