Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ Feng Ma
Florian Bruhin
Floris Bruynooghe
Gabriel Reis
George Kussumoto
Georgy Dyuldin
Graham Horler
Greg Price
Expand Down
11 changes: 9 additions & 2 deletions _pytest/outcomes.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,21 @@ def exit(msg):
exit.Exception = Exit


def skip(msg=""):
def skip(msg="", **kwargs):
""" skip an executing test with the given message. Note: it's usually
better to use the pytest.mark.skipif marker to declare a test to be
skipped under certain conditions like mismatching platforms or
dependencies. See the pytest_skipping plugin for details.

:kwarg bool allow_module_level: allows this function to be called at
module level, skipping the rest of the module. Default to False.
"""
__tracebackhide__ = True
raise Skipped(msg=msg)
allow_module_level = kwargs.pop('allow_module_level', False)
if kwargs:
keys = [k for k in kwargs.keys()]
raise TypeError('unexpected keyword arguments: {0}'.format(keys))
raise Skipped(msg=msg, allow_module_level=allow_module_level)


skip.Exception = Skipped
Expand Down
3 changes: 2 additions & 1 deletion _pytest/skipping.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,8 @@ def folded_skips(skipped):
# folding reports with global pytestmark variable
# this is workaround, because for now we cannot identify the scope of a skip marker
# TODO: revisit after marks scope would be fixed
if event.when == 'setup' and 'skip' in keywords and 'pytestmark' not in keywords:
when = getattr(event, 'when', None)
if when == 'setup' and 'skip' in keywords and 'pytestmark' not in keywords:
key = (key[0], None, key[2], )
d.setdefault(key, []).append(event)
l = []
Expand Down
1 change: 1 addition & 0 deletions changelog/2808.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add ``allow_module_level`` kwarg to ``pytest.skip()``, enabling to skip the whole module.
10 changes: 10 additions & 0 deletions doc/en/skipping.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ by calling the ``pytest.skip(reason)`` function:
if not valid_config():
pytest.skip("unsupported configuration")

It is also possible to skip the whole module using
``pytest.skip(reason, allow_module_level=True)`` at the module level:

.. code-block:: python

import pytest

if not pytest.config.getoption("--custom-flag"):
pytest.skip("--custom-flag is missing, skipping tests", allow_module_level=True)

The imperative method is useful when it is not possible to evaluate the skip condition
during import time.

Expand Down
45 changes: 42 additions & 3 deletions testing/test_skipping.py
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ def test_though(self):


def test_skip_reasons_folding():
path = 'xyz'
path = "xyz"
lineno = 3
message = "justso"
longrepr = (path, lineno, message)
Expand All @@ -680,10 +680,15 @@ class X(object):
ev2.longrepr = longrepr
ev2.skipped = True

l = folded_skips([ev1, ev2])
# ev3 might be a collection report
ev3 = X()
ev3.longrepr = longrepr
ev3.skipped = True

l = folded_skips([ev1, ev2, ev3])
assert len(l) == 1
num, fspath, lineno, reason = l[0]
assert num == 2
assert num == 3
assert fspath == path
assert lineno == lineno
assert reason == message
Expand Down Expand Up @@ -1005,6 +1010,40 @@ def test_func():
)


def test_module_level_skip_with_allow_module_level(testdir):
"""
Verify that using pytest.skip(allow_module_level=True) is allowed
"""
testdir.makepyfile("""
import pytest
pytest.skip("skip_module_level", allow_module_level=True)

def test_func():
assert 0
""")
result = testdir.runpytest("-rxs")
result.stdout.fnmatch_lines(
"*SKIP*skip_module_level"
)


def test_invalid_skip_keyword_parameter(testdir):
"""
Verify that using pytest.skip() with unknown parameter raises an error
"""
testdir.makepyfile("""
import pytest
pytest.skip("skip_module_level", unknown=1)

def test_func():
assert 0
""")
result = testdir.runpytest()
result.stdout.fnmatch_lines(
"*TypeError:*['unknown']*"
)


def test_mark_xfail_item(testdir):
# Ensure pytest.mark.xfail works with non-Python Item
testdir.makeconftest("""
Expand Down