Pytest: When writing many assert statements in the same test function, some of it fails, but how to know which assert statement/s is causing failure?

33 views Asked by At

Test file :

from RansomNote import Solution


def test_canConstruct():
    sol = Solution()
    assert sol.canConstruct('aa', 'aab') == True
    assert sol.canConstruct('xx','aaabc') == True
    assert sol.canConstruct('aab','ababa') == True

Ouput after running pytest -v :

==================================================================== short test summary info =====================================================================
FAILED Easy/test_ransomNote.py::test_canConstruct - AssertionError: assert False == True
======================================================================= 1 failed in 0.01s

QUESTION : First of all, is it ok to have many assert statements in the same test function or is it not recommended? In output it just says assertion error, how to know which assert statement is actually causing the failure? Is it better to create a new test function for each assert statement?

Tried pytest -v Expected which assert statement caused the failure. Output result : FAILED Easy/test_ransomNote.py::test_canConstruct - AssertionError: assert False == True

3

There are 3 answers

0
Dino Hensen On

Pytest will print a string that follows the assert, so you could do this:

from RansomNote import Solution


def test_canConstruct():
    sol = Solution()
    assert sol.canConstruct('aa', 'aab') == True, 'first one failed'
    assert sol.canConstruct('xx','aaabc') == True, 'second one failed'
    assert sol.canConstruct('aab','ababa') == True, 'third one failed'
0
larsks On

There's something missing from your output.

If I try to reproduce your issue using this code:

def working_function():
    return True


def failing_function():
    return False


def test_some_function():
    assert working_function()
    assert failing_function()

Running pytest -v shows clearly which assert statement is failing:

================================================================= FAILURES ==================================================================
____________________________________________________________ test_some_function _____________________________________________________________

    def test_some_function():
        assert working_function()
>       assert failing_function()
E       assert False
E        +  where False = failing_function()

test_assert.py:11: AssertionError
========================================================== short test summary info ==========================================================
FAILED test_assert.py::test_some_function - assert False
============================================================= 1 failed in 0.01s =============================================================

Note also that this:

assert working_function()

Is exactly equivalent to:

assert working_function() == True

That is, there's no reason to include the == True in your asssert statements.

0
Diego Torres Milano On

You can use parameters

@pytest.mark.parametrize("x, y", (("aa", "aab"), ("xx", "aaabc"), ("aab", "ababa")))
def test_canConstruct(x, y):
    sol = Solution()
    assert sol.canConstruct(x, y) is True

and get the results individually

x.py::test_canConstruct[aa-aab] PASSED                 [ 33%]
x.py::test_canConstruct[xx-aaabc] PASSED               [ 66%]
x.py::test_canConstruct[aab-ababa] PASSED              [100%]