pytest Exceptions - Part II

We've already seen how to test exceptions with pytest in part I. However what's going to happen if we didn't fully implement our method yet or don't want to test on different os platforms, language versions etc.?
For these kind of tests we can use skip and xfail:
  • A skip means that you expect your test to pass only if some conditions are met,
  • An xfail means that you expect a test to fail for some reason.
  • Let's assume we got a dummy method which calls a third party API;
    # utils.py
    from typing import Optional
    
    import requests
    
    from .exceptions import ParametersError, PaymentGatewayError, UserPermissionError
    
    
    def incomplete_business_logic_method(*args, **kwargs) -> Optional[str]:
        response = None
        try:
            response = expensive_calculation_method(*args, **kwargs)
        except APIGatewayError as exc:
            raise APIGatewayError() from exc
        except requests.exceptions.HTTPError as exc:
            if exc.response.status_code == 400:
                error = exc.response.json()
                code = error['code']
                message = error['message']
    
                if exc.code == 2001:
                    raise ParametersError(exc.code, exc.message) from exc
                else:
                    raise UserPermissionError(exc.code, exc.message) from exc
    
        return response
    And exceptions module looks like this:
    # exceptions.py
    class APIGatewayError(Exception):
        pass
    
    
    class PaymentGatewayError(APIGatewayError):
        def __init__(self, code, message):
            self.code = code
            self.message = message
    
    
    class ParametersError(PaymentGatewayError):
        pass
    
    
    class UserPermissionError(PaymentGatewayError):
        pass
    xfail
    You can use xfail marker to indicate that you expect a test to fail:
    # tests/test_utils.py
    import pytest
    
    from .exceptions import APIGatewayError
    
    
    @pytest.mark.xfail(raises=APIGatewayError)
    def test_incomplete_business_logic_method(self):
        ...
        return incomplete_business_logic_method(*args, **kwargs)
    If a test is only expected to fail under a certain condition — like in skipif,
    you can pass that condition as the first parameter:
    # tests/test_utils.py
    import pytest
    
    
    @pytest.mark.xfail(sys.version_info < (3, 6), reason="requires python3.6 or higher")
    def test_incomplete_business_logic_method(self):
        ...
        return incomplete_business_logic_method(*args, **kwargs)
    skip
    The simplest way to skip a test function is to mark it with the skip decorator which may be passed an optional reason:
    # tests/test_utils.py
    import pytest
    
    
    @pytest.mark.skip(reason="not implement this yet")
    def test_incomplete_business_logic_method(self):
        ...
        return incomplete_business_logic_method(*args, **kwargs)
    skipif
    If you wish to skip something conditionally then you can use skipif:
    # tests/test_utils.py
    import pytest
    
    
    @pytest.mark.skiWe’ve already seen how to test exceptions with pytest in part I. However what’s going to happen if we didn’t fully implement our method yet or don’t want to test on different os platforms, language versions etc.? For these kind of tests we can use skip and xfail: A skip means that you expect your test to pass only if some conditions are met, An xfail means that you expect a test to fail for some reason.pif(sys.version_info < (3, 6), reason="requires python3.6 or higher")
    def test_incomplete_business_logic_method(self):
        ...
        return incomplete_business_logic_method(*args, **kwargs)
    Addition
    You can show extra info on xfailed and skipped tests with -rxs:
    $ pytest -rxs
    Get more info on offical doc :skip and xfail.
    All done!

    25

    This website collects cookies to deliver better user experience

    pytest Exceptions - Part II