2

I have some problems with my test. I wanted to start my pytest adventure with some simple scripts(BMI counter in this case). I want to test once function but the test is going into all of them. If I have commented the input values the test pass.

Output:

$ pytest test_bmi.py
=========================================================================================== test session starts ============================================================================================
platform darwin -- Python 3.7.1, pytest-4.0.2, py-1.7.0, pluggy-0.8.0
rootdir: /Users/mateusz/Documents/Code_Me_Python/zajecia_python/Zajecia_1, inifile:
plugins: remotedata-0.3.1, openfiles-0.3.1, doctestplus-0.2.0, arraydiff-0.3
collected 0 items / 1 errors

================================================================================================== ERRORS ==================================================================================================
_______________________________________________________________________________________ ERROR collecting test_bmi.py _______________________________________________________________________________________
test_bmi.py:1: in <module>
    from bmi import count_bmi
bmi.py:14: in <module>
    main()
bmi.py:11: in main
    (mass, height) = users_data()
bmi.py:2: in users_data
    mass = float(input("Your weight: "))
../../../../anaconda3/lib/python3.7/site-packages/_pytest/capture.py:656: in read
    raise IOError("reading from stdin while output is captured")
E   OSError: reading from stdin while output is captured
--------------------------------------------------------------------------------------------- Captured stdout ----------------------------------------------------------------------------------------------
Your weight:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================================================================= 1 error in 0.16 seconds =========================================================================================

I have tried 'monkeypatch'(as mentioned in snippet), inputting the values into variables to pass them into test. Nothing helped.

bmi.py

def users_data():
    mass = float(input("Your weight: "))
    height = float(input("Your height: "))
    return mass, height

def count_bmi(mass, height):
    bmi = round(mass / (height**2), 2)
    return bmi

def main():
    (mass, height) = users_data()
    print(count_bmi(mass, height))

main()

test_bmi.py

from bmi import count_bmi

def test_count_bmi(monkeypatch):
    ans1 = '60'
    ans2 = '1.7'
    ans3 = '20.76'
    with monkeypatch.context() as m:
        m.setattr('builtins.input', lambda x: ans1, ans2)
        result = count_bmi(ans1, ans2)

    assert result == ans3

If I comment input variables

 def test_count_bmi(self):
     count_bmi.input = lambda: ''
     output = count_bmi(60, 1.7)  
     assert output == '20.76'

I expect to pass the test.

1 Answer 1

1

The problem is the call main() on module level. This will execute the main function on bmi module import; use the common idiom for circumventing this:

# bmi.py

def users_data():
    ...

def count_bmi(mass, height):
    ...

def main():
    ...

if __name__ == "__main__":
    # execute only if run as a script
    main()

See the topic __main__ — Top-level script environment in Python docs if you want to know more; also, SO has a stellar question for this: What does if __name__ == “__main__”: do?

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.