pytest-dev / pytest-dev/pytest

get_closest_marker is working unexpectedly

Open
#14,329 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

topic: marks type: bug
Dominant language
Python
Stars
14.5k
Forks
3.4k
Avg merge
2d 9h
Merged PRs (30d)
35

Description

  • a detailed description of the bug or problem you are having
  • output of pip list from the virtual environment you are using
  • pytest and operating system versions
  • minimal example if possible

Description:
get_closest_marker is working unexpectedly for me
I redefine the mark on the class in which the test is defined, but I get the mark of the parent of the class, i.e. a deeper mark than expected.

Versions:
pytest v9.0.2, Windows 10

Minimal Example:

from typing import cast

import pytest


@pytest.mark.some_mark(data=0)
class TestParent:
    def test_case(self, request: pytest.FixtureRequest):
        some_mark = self.get_mark(request)
        assert some_mark.kwargs.get("data") == 0

    def get_mark(self, request: pytest.FixtureRequest):
        some_mark = cast(pytest.Function, request.node).get_closest_marker("some_mark")
        assert some_mark
        return some_mark


@pytest.mark.some_mark(data=1)
class TestChild(TestParent):
    def test_case(self, request: pytest.FixtureRequest):
        some_mark = self.get_mark(request)
        assert some_mark.kwargs.get("data") == 1

Test: test_closest_mark.py::TestChild::test_case fails:

>       assert some_mark.kwargs.get("data") == 1
E       AssertionError: assert 0 == 1
E        +  where 0 = <built-in method get of dict object at 0x000001AC94A73740>('data')
E        +    where <built-in method get of dict object at 0x000001AC94A73740> = {'data': 0}.get
E        +      where {'data': 0} = Mark(name='some_mark', args=(), kwargs={'data': 0}).kwargs

In my understanding, the mark defined on TestChild is a closer mark than the mark defined on TestParent

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the minimal example in test_closest_mark.py::TestChild::test_case and inspect how get_closest_marker("some_mark") traverses markers for inherited test classes. Reproduce the failure on pytest v9.0.2, then add or adjust a regression test so the behavior for TestChild and TestParent is explicit and the test passes with the intended closest mark.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
testing
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
64/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.