Home > Mobile >  Python Unittest on mid function print statements
Python Unittest on mid function print statements

Time:01-05

I am struggling to find a way of doing a unittest on a function whiles using the error message from an assert statement. Any help would be appreciated .

def divisible_by_five(x):
    assert x % 5 == 0, "The number is not divisible by 5"
    print("The number is divisible by 5")

CodePudding user response:

Without Knowing how your test looks like. I decide to write a test and also modified your divisible_by_five(x) to return a str just to show you how it works.

import unittest


def divisible_by_five(x):
    assert x % 5 == 0, "The number is not divisible by 5"
    print("The number is divisible by 5")
    return "The number is divisible by 5"


class TestDivisibleByFive(unittest.TestCase):
    def test_divisible_by_five(self):
        # Test if the function works as expected for a number divisible by 5
        self.assertEqual(divisible_by_five(20), "The number is divisible by 5")

        # Test if the function raises an exception for a number not divisible by 5        
        with self.assertRaises(AssertionError) as err:
            divisible_by_five(11)
        self.assertEqual(str(err.exception), "The number is not divisible by 5")

        
if __name__ == "__main__":
    unittest.main()

CodePudding user response:

Failing assert statements raise an AssertionError with a message, which can be tested just like any other kind of exception instance by using a pytest.raises context manager.

It is possible to test the print output and the assertion message like this:

import pytest

from mymod import divisible_by_five


def test_divisible_by_five(capsys):
    divisible_by_five(10)
    out, err = capsys.readouterr()
    assert out == "The number is divisible by 5\n"


def test_not_divisible_by_five():
    with pytest.raises(AssertionError("The number is not divisible by 5")):
        divisible_by_five(11)

The usage of providing an exception instance to pytest.raises requires installing my plugin pytest-raisin.

An equivalent test which does not use the plugin could be written like this:

import re

def test_not_divisible_by_five():
    expected_message = "The number is not divisible by 5"
    with pytest.raises(AssertionError, match=f"^{re.escape(expected_message)}$"):
        divisible_by_five(11)

CodePudding user response:

You can just use try: ... except to wrap the error around custom stuff:

def test(x: float):
    try:
        assert x % 5 == 0
        print(f"{x} is divisible by 5")
    except AssertionError as err:
        print(f"{x} is not divisible by 5")
        raise err


test(5)
# 5 is divisible by 5
test(3)
# 4 is not divisible by 5
# Traceback (most recent call last):
#   File ..., line 11, in <module>
#     test(4)
#   File ..., line 7, in test
#     raise err
#   File ..., line 3, in test
#     assert x % 5 == 0
# AssertionError
  • Related