12

I'm using py.test for a somewhat unconventional application. Basically, I want to have user interaction in a test via print() and input() (this is Python 3.5). The ultimate goal is to have semi-automated testing for hardware and multi-layered software which cannot be automatically tested even in principle. Some test cases will ask the testing technician to do something (to be confirmed by enter or press any key or similar on the console) or ask them to take a simple measurement or visually confirm something (to be entered on the console).

Example of what I (naively) want to do:

def test_thingie():
    thingie_init('red')
    print('Testing the thingie.')
    # Ask the testing technician to enter info, or confirm that he has set things up physically
    x = int(input('Technician: How many *RED* widgets are on the thingie? Enter integer:')) 
    assert x == the_correct_number

This works with when the test file is called with pytest -s to prevent stdin and stdout capturing, but the documented means (with capsys.disabled()) in the py.test documentation don't work since they only affect stdout and stderr.

What's a good way to make this work using code in the py.test module, no command line options, and ideally per-test?

The platform, for what it's worth, is Windows and I'd prefer not to have this clobber or get clobbered by the wrapping of stdin/out/whatever that results from nested shells, uncommon shells, etc.

3
  • What kind of testing do you want to do? Unit tests, integration tests, behavior tests, usability tests,...? It looks like you are trying to blend all of them. BTW every software can be tested in principle.
    – Klaus D.
    Commented Dec 17, 2016 at 4:13
  • What I am trying to do specifically is make the input() built-in work in Pytest unit cases the same way it does in interactive python or scripts.
    – ikrase
    Commented Dec 19, 2016 at 17:38
  • Did you find a good solution to this problem!? I am basically trying to do the exact same thing testing, multiple software layers interfacing with hardware requireing a technician to operate parts of the hardware between tests. Commented Feb 9, 2019 at 13:42

1 Answer 1

3

no command line options

Use pytest.ini option or env variable to avoid using command line option every time.

ideally per-test?

Use function scoped fixture to take user input. Example code:

# contents of conftest.py
import pytest
@pytest.fixture(scope='function')
def take_input(request):
    val = input(request.param)
    return val



#Content of test_input.py
import pytest

@pytest.mark.parametrize('prompt',('Enter value here:'), indirect=True)
def test_input(take_input):
    assert take_input == "expected string"

Not the answer you're looking for? Browse other questions tagged or ask your own question.