PytestUnknownMarkWarning: Unknown pytest.mark.xxx - is this a typo?

44.4k views Asked by At

I have a file called test.py with the following code:

import pytest

@pytest.mark.webtest
def test_http_request():
    pass

class TestClass:
    def test_method(self):
        pass

pytest -s test.py passed but gave the following warnings:

pytest -s test.py
=============================== test session starts ============================
platform linux -- Python 3.7.3, pytest-5.2.4, py-1.8.0, pluggy-0.13.1
rootdir: /home/user
collected 2 items

test.py ..

=============================== warnings summary ===============================
anaconda3/lib/python3.7/site-packages/_pytest/mark/structures.py:325
  ~/anaconda3/lib/python3.7/site-packages/_pytest/mark/structures.py:325:
    PytestUnknownMarkWarning: Unknown pytest.mark.webtest - is this a typo?  You can register
    custom marks to avoid this warning - for details, see https://docs.pytest.org/en/latest/mark.html
    PytestUnknownMarkWarning,

-- Docs: https://docs.pytest.org/en/latest/warnings.html
=============================== 2 passed, 1 warnings in 0.03s ===================

Environment: Python 3.7.3, pytest 5.2.4, anaconda3

What is the best way to get rid of the warning message?

7

There are 7 answers

1
gold_cy On

To properly handle this you need to register the custom marker. Create a pytest.ini file and place the following inside of it.

[pytest]
markers =
    webtest: mark a test as a webtest.

Next time you run the tests, the warning about the unregistered marker will not be there.

0
Valentin Kuhn On

Another more complete and up-to-date (pytest 7.4.0 at the time of writing) answer also incorporating other configuration file formats such as pyproject.toml, e.g., for poetry users. The answer is based on pytest docs on registering marks and the pytest example on custom markers:

Registering markers

Possibility 1: pytest.ini

You can define a marker with explanation (webtest) and without (other) in pytest.ini:

[pytest]
markers =
    webtest: mark a test as a webtest
    
    other

Possibility 2: pyproject.toml

If you're already using a PEP-518 build system (e.g., poetry) with pyproject.toml, you can also specify pytest options there instead of adding an additional pytest.ini. The pyproject.toml file format is slightly different:

[tools.pytest.ini_options]
markers = [
    "webtest: mark a test as a webtest",
    "other",
]

Possibility 3: conftest.py

Another option is to register the markers in conftest.py, e.g., next to your marker's code. This is recommended for pytest plugin authors.

def pytest_configure(config):
    config.addinivalue_line("markers", "webtest: mark a test as a webtest")
    config.addinivalue_line("other")

Markers with arguments

Either way, you can register markers with arguments using mymarker(myarg): a marker receiving one argument.

Checking successful registration with pytest

Either, run all your tests and check for any PytestUnknownMarkWarnings in the output or run pytest --strict-markers to run tests and fail on unknown markers.

Alternatively, run pytest --markers which will only output available markers without running the tests. Successfully registered markers should be contained in the pytest --markers output. Markers registered in conftest.py will only be shown in the output if you're launching pytest in the directory containing this conftest.py - but they will work, i.e., fix the PytestUnknownMarkWarning, in nested directories, too.

4
Jonathan L On

@gold_cy's answer works. If you have too many custom markers need to register in pytest.ini, an alternative way is to use the following configuration in pytest.ini:

[pytest]
filterwarnings =
    ignore::UserWarning

or in general, use the following:

[pytest]
filterwarnings =
    error
    ignore::UserWarning

the configuration above will ignore all user warnings, but will transform all other warnings into errors. See more at Warnings Capture

test.py (updated with two custom markers)

import pytest

@pytest.mark.webtest
def test_http_request():
    print("webtest::test_http_request() called")

class TestClass:
    @pytest.mark.test1
    def test_method(self):
        print("test1::test_method() called")

Use the following commands to run desired tests:

pytest -s test.py -m webtest
pytest -s test.py -m test1
0
bexelfee On

The best way to get rid of the message is to register the custom marker as per @gold_cy's answer.

However if you just wish to suppress the warning as per Jonathon's answer, rather than ignoring UserWarning (which will suppress all instances of the warning regardless of their source) you can specify the particular warning you want to suppress like so (in pytest.ini):

ignore::_pytest.warning_types.PytestUnknownMarkWarning

Note: For third party libraries/modules the full path to the warning is required to avoid an _OptionError exception

0
Kashyap On

If you don't have pytest.ini and don't wanna create one just for this then you can also register it programmatically in conftest.py as described here:

def pytest_configure(config):
    # register an additional marker
    config.addinivalue_line(
        "markers", "env(name): mark test to run only on named environment"
    )
0
swimmer On

To add to the existing answers - custom markers can also be registered in pyproject.toml:

# pyproject.toml

[tool.pytest.ini_options]
markers = [
    "webtest: mark a test as a webtest.",
]

Related docs.

0
Balaji K On

without updating pytest.ini, we can ignore warning using --disable-warnings

We can also use --disable-pytest-warnings

Example using your case: pytest -s test.py -m webtest --disable-warnings