Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pytest.skip for a specific exception

Tags:

python

pytest

I have some test codes to check contents of target file like :

sc = samplechecker(json_root, 'target_file_to_check', {params})
result = sc.run()
res = sc.getId()
taskIds.append(res['data']['Id'])
assert result

And want to skip test if target file is not exist, so modified the code :

try :
    sc = samplechecker(json_root, 'target_file_to_check', {params})
except FileNotFoundError as exc:
    pytest.skip(f"!!! Target file {exc.filename} not found !!!")

result = sc.run()
res = sc.getId()
taskIds.append(res['data']['Id'])
assert result

This works fine for this one case, but I have several similar test modules so would like to apply this to all other cases as well. So tried to add pytest_exception_interact in conftest.py :

in conftest.py :

import pytest

@pytest.hookimpl()
def pytest_exception_interact(node, call, report):
    excinfo = call.excinfo
    excvalue = excinfo.value

    if excinfo.type == FileNotFoundError:
        pytest.skip(f"!!! Target file {excvalue.filename} not found !!!")

But it doesn't work the way I want. Just failed with many of internal error.

...
INTERNALERROR>   File "/home/jyoun/work/venv_xdr-ac/lib/python3.7/site-packages/pluggy/callers.py", line 208, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/home/jyoun/work/venv_xdr-ac/lib/python3.7/site-packages/pluggy/callers.py", line 80, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/home/jyoun/work/venv_xdr-ac/lib/python3.7/site-packages/pluggy/callers.py", line 187, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/home/jyoun/work/venv_xdr-ac/git/SOC-SampleCode/api_reference/test/conftest.py", line 26, in pytest_exception_interact
INTERNALERROR>     pytest.skip(f"!!! Target file {excvalue.filename} not found !!!")
INTERNALERROR>   File "/home/jyoun/work/venv_xdr-ac/lib/python3.7/site-packages/_pytest/outcomes.py", line 112, in skip
INTERNALERROR>     raise Skipped(msg=msg, allow_module_level=allow_module_level)
INTERNALERROR> Skipped: !!! Target file ../sample/targetfile1 not found !!!

How can I reach for the target I want?

like image 795
Rivian Avatar asked Dec 18 '25 09:12

Rivian


1 Answers

The reason you see this INTERNAL_ERROR is because you are raising an exception inside the hook implementation which is a tiny plugin for pytest.

In other words, you implemented a small plugin to check if a test failed due to a given exception, if that's true, you raise an exception. Instead you should look on how to set that test (I think it is represented as the node here) to skipped and add the skip description at proper place.

If this is something you would use in many other tests, I would advise you to invest some time to do that.

On the other hand, if it is sporadically used and you want to see it closer to you test, you can implement a function decorator to capture the exception and raise the skip exception during the test run time.

Example:

def skip_on(exception, reason="Default reason"):
    # Func below is the real decorator and will receive the test function as param
    def decorator_func(f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            try:
                # Try to run the test
                return f(*args, **kwargs)
            except exception:
                # If exception of given type happens
                # just swallow it and raise pytest.Skip with given reason
                pytest.skip(reason)

        return wrapper

    return decorator_func

Then decorate your test method like this:

@skip_on(FileNotFoundError, reason="A good reason to skip")
def test_something():
    ...
    sc = samplechecker(json_root, 'target_file_to_check', {params})
    result = sc.run()
    res = sc.getId()
    taskIds.append(res['data']['Id'])
    assert result
    ...
like image 70
lucrib Avatar answered Dec 20 '25 22:12

lucrib