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.

sanyassh
  • 8,100
  • 13
  • 36
  • 70
Hehson
  • 23
  • 4

1 Answers1

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?

hoefling
  • 59,418
  • 12
  • 147
  • 194