question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Stricter arg/kwarg handling in pytest.mark.skip; skip vs. skipif

See original GitHub issue

Apologies if there already is an issue about this, I tried to search, but it’s a bit tricky to find a proper term for this.

It seems like a somewhat common issue for people to accidentally use @pytest.mark.skip when they actually wanted skipif.

Strangely enough, pytest will happily accept something like:

import pytest

@pytest.mark.skip(False, reason="bla")
def test_skipped():
    pass

and skip the test.

This is due to how arguments are handled in the marker:

https://github.com/pytest-dev/pytest/blob/cd783eba03dabab5bc833009d6fc9083d8afe58d/src/_pytest/skipping.py#L186-L193

Yet our reference documentation actually claims:

pytest.mark.skip(*, reason=None)

which isn’t true.

I see a couple of ways how to fix this. By decreasing impact of the respective changes:

  • Make the skip marker actually take a condition as first argument, so that it replaces skipif entirely, and deprecate the latter. The difference between skip / skipif and xfail (but no xfailif) has always bothered me to be honest.
  • Deprecate and warn about using pytest.mark.skip with a positional argument (i.e. make the signature consistent with what the docs claim).
  • Continue to accept the reason as positional argument, but at least show an error if both are given (i.e. like Python would if the signature was def skip(reason):).

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:4
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
nicoddemuscommented, Mar 3, 2021

@The-Compiler yeah you are right. A quick search shows that there are many usages without the keyword argument (@pytest.mark.skip(reason='Unimplemented Test')) so those would break if we make the skip and skipif signatures equal; I thought those would be few but that doesn’t seem to be the case.

With that in mind, I’m leaning towards just enforcing the signature to this:

def skip(reason=None):

(a single argument, either positional or reason keyword)

As you point out, making skipif an alias to skipif will force thousands of test suites to change, which I’m not sure it worth doing at this point.

1reaction
nicoddemuscommented, Mar 3, 2021

I definitely like the idea of enforcing the signature!

I also agree with @Zac-HD though that we shouldn’t deprecate skipif because I believe it is much more used than skipif currently (skip is relatively recent).

Currently we have these documented signatures:

pytest.mark.skip(*, reason=None)
pytest.mark.skipif(condition, *, reason=None)

Make the skip marker actually take a condition as first argument, so that it replaces skipif entirely, and deprecate the latter. The difference between skip / skipif and xfail (but no xfailif) has always bothered me to be honest.

I like that, except for the “deprecate the latter” part.

IIUC then, the steps to accomplish that would be:

  1. Update pytest.mark.skip signature to:

    pytest.mark.skip(condition: Union[str, bool]=True, *, reason: Optional[str]=None)
    

    This makes it a drop-in replacement for skipif.

  2. Update all skipif examples in the docs to use skip.

  3. Mention skipif in the docs just as an alias to skip, commenting about the historical reasons that led both to exist, however also mention that we don’t plan to remove it anytime soon, or ever.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to use skip and xfail to deal with tests that cannot succeed
Here is an example of marking a test function to be skipped when run on an interpreter earlier than Python3.10: import sys @pytest.mark.skipif...
Read more >
API Reference — pytest documentation - Read the Docs
It is better to use the pytest.mark.skipif marker when possible to declare a test to be skipped under certain conditions like mismatching platforms...
Read more >
Skip test depending on parameter in py.test - Stack Overflow
So we can wrap test class with: @pytest.mark.skipif("pytest.param == 'value'") class TestSmth ...
Read more >
Reference — pytest documentation
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...
Read more >
pytest Changelog - pyup.io
This was changed for consistency with :func:`pytest.mark.skip ... Before, such tests were silently skipped, and the positional argument ignored.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found