Skip to content

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

@The-Compiler

Description

@The-Compiler

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:

for mark in item.iter_markers(name="skip"):
if "reason" in mark.kwargs:
reason = mark.kwargs["reason"]
elif mark.args:
reason = mark.args[0]
else:
reason = "unconditional skip"
return Skip(reason)

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):).

Metadata

Metadata

Assignees

Labels

topic: marksrelated to marks, either the general marks or builtin

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions