Skip to content

Is it possible to prompt the user to do something during py.test runs? #4210

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
GlenNicholls opened this issue Oct 21, 2018 · 10 comments
Closed
Labels
type: question general question, might be closed after 2 weeks of inactivity

Comments

@GlenNicholls
Copy link

I am going to be writing a full system test for our customer to be able to check all of our systems during configuration after unit tests pass to ensure everything is working properly. For unit testing the code, py.test works great. However, we have a PCB that provides critical information during testing and need to be able to prompt the user to perform certain tasks so that the system can check these conditions to ensure they are as expected. Here is a simple example of what I am trying to do in a test function/class:

def test_pcb_button()
    print('press the button') # or something similar to print in py.test to force it to console
    print('does the led turn on? [y/n]')
    assert user_input() == 'y'
@Zac-HD Zac-HD added the type: question general question, might be closed after 2 weeks of inactivity label Oct 21, 2018
@RonnyPfannschmidt
Copy link
Member

Pytest isn't designed to manage manual tests, I wonder if there are 3rd party tools that support this

@nicoddemus
Copy link
Member

There is pytest-interactive, which interactively lets you select which tests to run. It might be a starting point to write a plugin which lets tests obtain user input.

I believe we can close this though, as pytest isn't designed for this as @RonnyPfannschmidt mentioned.

@bilderbuchi
Copy link
Contributor

There is actually a solution (workaround?) in that you can temporarily suspend capture to handle the user interaction (suggested by @nicoddemus himself, even):
#1599 (comment) (you should also set _in=True in the suspendcapture call.
I integrated this into a fixture to have some user interaction only for specific tests with an electronic device during testing, quite similar to your case.

@bilderbuchi
Copy link
Contributor

Also, at the time it was great to see that it was possible to use pytest in this hardware-testing scenario, even if it may not be designed for this... ;-)

@blueyed
Copy link
Contributor

blueyed commented Dec 22, 2018

@bilderbuchi
Note that the example from SO does not work, even when using with capmanager.global_and_fixture_disabled(): in the module scoped fixture.

It only works for me when used in the test itself, but not as a fixture.

@bilderbuchi
Copy link
Contributor

Hm, thanks, i'll have to check again then, it's been a while since I ran that code, it worked at the time at least.

@bilderbuchi
Copy link
Contributor

bilderbuchi commented Jan 1, 2019

@blueyed I have updated the SO answer to the new names suspend_global_capture and resume_global_capture and confirmed that it works with pytest 4.0.2.
Presumably using the global_and_fixture_disabled context manager does not work in your case because it has in_=False instead of True as in the SO answer.

@blueyed
Copy link
Contributor

blueyed commented Jan 14, 2019

@bilderbuchi
Just for reference: what I've meant is that it does not work when used via a fixture to disable capturing in the tests itself:

import pytest


@pytest.fixture(scope="module")
def disable_capture_module(pytestconfig):
    capmanager = pytestconfig.pluginmanager.getplugin('capturemanager')

    # capmanager.suspend_global_capture(in_=True)
    # yield
    # capmanager.resume_global_capture()

    with capmanager.global_and_fixture_disabled():
        yield


def test_with_fixture(disable_capture_module):
    for i in range(1, 10):
        print(i)


def test_inline(pytestconfig):
    capmanager = pytestconfig.pluginmanager.getplugin('capturemanager')

    with capmanager.global_and_fixture_disabled():
        for i in range(1, 10):
            print(i)

Will result in the following when run with -v:

platform linux -- Python 3.6.8, pytest-4.0.2, py-1.7.0, pluggy-0.8.0 -- …
…
collected 2 items

t-disable-capture.py::test_with_fixture PASSED
t-disable-capture.py::test_inline 1
2
3
4
5
6
7
8
9
PASSED

@nicoddemus
Is there a method to make this work via a fixture?

@nicoddemus
Copy link
Member

Not sure from the top of my head... at first glance it should probably work.

@bilderbuchi
Copy link
Contributor

Ah I understand now. No idea why that is, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: question general question, might be closed after 2 weeks of inactivity
Projects
None yet
Development

No branches or pull requests

6 participants