'How to Run Pytest On If Else Statement?

I successfully run Pytest for calculate_bmi function, but failed to run Pytest for bmi_index function. May I know how to run Pytest for bmi_index function?

def main():
    weight = float(input('Enter weight (kg): '))
    height = float(input('Enter height (cm): '))

    bmi = calculate_bmi(weight, height)
    bmi_index(bmi)
    
def calculate_bmi(weight, height):
    bmi = round(10000 * weight / (height ** 2))
    return bmi

def bmi_index(bmi):
    if bmi <= 18.5:
        print('You are underweight.')
    elif bmi <= 24.9:
        print('You are normal weight.')
    elif bmi <= 29.9:
        print('You are overweight.')
    else: 
        print('You are obese.') 

if __name__ == "__main__":
    main()

I've tried the following, but test failed (for test_bmi_index). The error was: AssertionError: assert None == 'You are obese.' I think it means there is no test to perform, but I'm not sure how. Can you assist me? Thank you very much.

from practice4 import calculate_bmi, bmi_index
import pytest
from pytest import approx


def test_calculate_bmi():
    """Verify that the calculate bmi function works correctly."""
    assert calculate_bmi(47, 154) == approx(20)
    assert calculate_bmi(-95, 175) == approx(-31)
    assert calculate_bmi(4.5, 1.54) == approx(18975)

def test_bmi_index():
    """Verify that the bmi_index function works correctly."""
    assert bmi_index(31) == 'You are obese.'


pytest.main(["-v", "--tb=line", "-rN", __file__])

========================= test session starts ==========================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- C:\Users\iamsp\AppData\Local\Programs\Python\Python39\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\iamsp\Documents\Intro To Python Development
collected 2 items

test_practice4.py::test_calculate_bmi PASSED                      [ 50%]
test_practice4.py::test_bmi_index FAILED                          [100%]

=============================== FAILURES ===============================
c:\Users\iamsp\Documents\Intro To Python Development\test_practice4.py:14: AssertionError: assert None == 'You are obese.'
===================== 1 failed, 1 passed in 0.06s ======================
PS C:\Users\iamsp\Documents\Intro To Python Development> 


Solution 1:[1]

Printing is not the same as returning. The function bmi_index prints text but doesn't return anything (thus the None return value). You can solve this by adding a return statement:

def bmi_index(bmi):
    if bmi <= 18.5:
        return 'You are underweight.'
    elif bmi <= 24.9:
        return 'You are normal weight.'
    elif bmi <= 29.9:
        return 'You are overweight.'
    else: 
        return 'You are obese.'

or, if you prefer:

def bmi_index(bmi):
    if bmi <= 18.5:
        print('You are underweight.')
        return 'You are underweight.'
    elif bmi <= 24.9:
        print('You are normal weight.')
        return 'You are normal weight.'
    elif bmi <= 29.9:
        print('You are overweight.')
        return 'You are overweight.'
    else: 
        print('You are obese.')
        return 'You are obese.'

Solution 2:[2]

The error was: AssertionError: assert None == 'You are obese.' I think it means there is no test to perform, but I'm not sure how.

That's not what that means. It means you're asserting two things are equal, but they're not. None is not equal to the string 'You are obese.' on the line

assert bmi_index(31) == 'You are obese.'

That's because the function call bmi_index(31) returns None implicitly, since internally you only print the results without returning anything. Make that function return a value instead and your test should work.

def bmi_index(bmi):
    if bmi <= 18.5:
        return 'You are underweight.'
    elif bmi <= 24.9:
        return 'You are normal weight.'
    elif bmi <= 29.9:
        return 'You are overweight.'
    else: 
        return 'You are obese.'

If you want to see those messages on the screen, print the return value after you call the function.

Solution 3:[3]

you can also redirect stdout to test it.

from practice4 import calculate_bmi, bmi_index
import pytest
from pytest import approx
from contextlib import redirect_stdout
from io import StringIO


def test_calculate_bmi():
    """Verify that the calculate bmi function works correctly."""
    assert calculate_bmi(47, 154) == approx(20)
    assert calculate_bmi(-95, 175) == approx(-31)
    assert calculate_bmi(4.5, 1.54) == approx(18975)

def test_bmi_index():
    """Verify that the bmi_index function works correctly."""
    stdout = StringIO()
    with redirect_stdout(stdout):
        bmi_index(31)
    assert stdout.getvalue() == 'You are obese.'


pytest.main(["-v", "--tb=line", "-rN", __file__])

this is better then changing the original function because you can see that print adds a newline character.

AssertionError: assert 'You are obese.\n' == 'You are obese.'

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 QWERTYL
Solution 2 Bill the Lizard
Solution 3 steviestickman