Search code examples
pythonpython-2.7python-3.xunit-testingpytest

Can I handle multiple asserts within a single Python pytest method?


I am writing tests with pytest, and I ran into a problem: I have a test which testing some variable, and then I perform some heavy calculation, and after that I want to perform another test.

The problem is that if the first assert fails, the whole test fails, and pytest does not perform the second test. The code:

class TestSomething:
    def tests_method(self, some_variables):
        # Some actions that take a lot of time!
        assert some_var == 1
        # Some actions that take a lot of time!
        assert some_var == 2

I'm aware that this test method can be separated into 2 methods, but the performance issue here is crucial.

Is there a way I can run 2 asserts in one method?


Solution

  • Usually, I just let the test fail on the first assertion. However, if you really want to do more than one comparison, compare tuples. Here's a simple example:

    def foo(x):
        return x + 1
    
    
    def bar(y):
        return y - 1
    
    
    def test_foo():
        # some expensive calculation                                                                                                                                    
        a = foo(10)
    
        # another expensive calculation                                                                                                                                 
        b = bar(10)
    
        assert (a, b) == (10, 9)
    

    When I run that with pytest, it shows me both values:

    $ pytest scratch.py
    ============================= test session starts =============================
    platform linux2 -- Python 2.7.12, pytest-3.0.7, py-1.4.33, pluggy-0.4.0
    rootdir: /home/don/workspace/scratch, inifile:
    collected 1 items
    
    scratch.py F
    
    ================================== FAILURES ===================================
    __________________________________ test_foo ___________________________________
    
    def test_foo():
    # some expensive calculation
    a = foo(10)
    
    # another expensive calculation
    b = bar(10)
    
    >       assert (a, b) == (10, 9)
    E       assert (11, 9) == (10, 9)
    E         At index 0 diff: 11 != 10
    E         Use -v to get the full diff
    
    scratch.py:16: AssertionError
    ========================== 1 failed in 0.02 seconds ===========================
    

    I also tried using and to combine comparisons, but that doesn't work because of short circuiting. For example, I tried this assertion:

    assert a == 10 and b == 9
    

    Pytest reported this failure:

    >       assert a == 10 and b == 9
    E       assert (11 == 10)
    

    It doesn't report the value of b unless you use the --showlocals option.