pythonunit-testinginputpytestmonkeypatching

With pytest, for multi-input function looping, how do i assert the answers that i expect based on the responses?


I have referenced theY4Kman's accepted answer here. https://stackoverflow.com/a/59998012/27327525

How do I give my assertions iteratively so I can test the inputs 1 after another. This code isn't working passed the first input.

def test_test_get_genre_rock(monkeypatch):
    responses = iter(['rock','ska','punk'])
    monkeypatch.setattr('builtins.input', lambda _: next(responses))
    genre = str(input("Select 1 to 5 genres   -   press 'ENTER' when done: ")).lower()
    assert genre == "rock"
    assert genre == "ska"     # Obviously giving multiple assert statements is wrong

This code gives enter image description here

And if I try to assert multiple values in line with commas separating, it never picks up the second argument.

def test_test_get_genre_rock(monkeypatch):
    responses = iter(['rock','ska','punk'])
    monkeypatch.setattr('builtins.input', lambda _: next(responses))
    genre = str(input("Select 1 to 5 genres   -   press 'ENTER' when done: ")).lower()
    assert genre == "rock", "ska"

assert genre == "rock", "ska"     # is exactly the same
assert genre == "rock"            # as this

It seems like the responses = iter(['rock','ska','punk']) isn't really iterating.

A final note - Interestingly, when I assert using 'or' operators, it accepts my test.

assert genre == "rock" or genre == "ska" or genre == "punk"

But I think this is just saying "any of the values in the responses list", which is not really the point of my test. I want the first value (response[0]), then the second (response[1]), etc, to be checked.


Solution

  • You should call the input multiple times:

    def test_test_get_genre_rock(monkeypatch):
        responses = iter(['rock','ska','punk'])
        monkeypatch.setattr('builtins.input', lambda _: next(responses))
        genre = str(input("Select 1 to 5 genres   -   press 'ENTER' when done: ")).lower()
        assert genre == "rock"
        genre = str(input("Select 1 to 5 genres   -   press 'ENTER' when done: ")).lower()
        assert genre == "ska"
        genre = str(input("Select 1 to 5 genres   -   press 'ENTER' when done: ")).lower()
        assert genre == "punk"
    
    

    Or you can use a for loop:

    def test_test_get_genre_rock(monkeypatch):
        responses = iter(['rock','ska','punk'])
        monkeypatch.setattr('builtins.input', lambda _: next(responses))
        genres = [str(input("")) for _ in range(3)]
        assert genres == ['rock','ska','punk']