Hugo
Hugo

Reputation: 29334

Skipping an exception in all Python tests

I'm using Python's unittest with pytest for integration testing a library against a third-party API.

Some of the API calls are temporarily returning an error which raises a specific exception in my code. This behaviour is fine in the code.

However, rather than having the tests fail, I'd rather skip these temporary errors.

I have over 150 tests. Rather than rewriting each and every test like this:

class TestMyLibrary(unittest.TestCase):

    def test_some_test(self):
        try:
            // run the test as normal
            // assert the normal behaviour
        except SomeException:
            // skip the test

    def test_some_other_test(self):
        try:
            // run the test as normal
            // assert the normal behaviour
        except SomeException:
            // skip the test

Can I rather wrap them all somehow at the class level, or similar?

Upvotes: 1

Views: 7445

Answers (3)

murison
murison

Reputation: 3983

had the same problem (instable 3rd party library, waiting for fix...). ended up with something like this:

def pytest_runtest_makereport(item, call):
    from _pytest.runner import pytest_runtest_makereport as orig_pytest_runtest_makereport
    tr = orig_pytest_runtest_makereport(item, call)

    if call.excinfo is not None:
        if call.excinfo.type == SomeExceptionFromLibrary:
            tr.outcome = 'skipped'
            tr.wasxfail = "reason: SomeExceptionFromLibrary. shame on them..."

    return tr

works like a charm

Upvotes: 0

Hugo
Hugo

Reputation: 29334

This can be done with a decorator. For example:

def handle_lastfm_exceptions(f):
    def wrapper(*args, **kw):
        try:
            return f(*args, **kw)
        except pylast.WSError as e:
            if (str(e) == "Invalid Method - "
                          "No method with that name in this package"):
                msg = "Ignore broken Last.fm API: " + str(e)
                print(msg)
                pytest.skip(msg)
            else:
                raise(e)
    return wrapper

And then decorate the problematic functions:

class TestMyLibrary(unittest.TestCase):

    @handle_lastfm_exceptions
    def test_some_bad_test(self):
        // run the test as normal
        // assert the normal behaviour

    def test_some_good_test(self):
        // run the test as normal
        // assert the normal behaviour

Upvotes: 0

wa11a
wa11a

Reputation: 181

If you expect this exception why don't you check its raised when it should? You can use :

pytest.raises(Exceptiontype, Foo())

Upvotes: 1

Related Questions