11"""PyTest Config File."""
2+ from __future__ import annotations
23
34import os
5+ import re
46
57import pytest
68from _pytest .terminal import TerminalReporter
79
10+ PYTEST_CHECK_TEST_DUPLICATE = int (os .environ .get ("PYTEST_CHECK_TEST_DUPLICATE" , "1" ))
11+
12+
13+ def get_max_test_id_length () -> int :
14+ """Return max test id length."""
15+ return int (os .environ .get ("PYTEST_MAX_TEST_ID_LENGTH" , "60" ))
16+
17+
18+ def get_test_id_regex () -> None | re .Pattern [str ]:
19+ """Return regex to use for checking test ids."""
20+ if int (os .environ .get ("PYTEST_CHECK_TEST_ID_REGEX" , "1" )):
21+ return re .compile (r"^\w+$" )
22+ return None
23+
824
925def pytest_sessionfinish (session : pytest .Session ) -> None :
1026 """Assure passed test match PYTEST_REQPASS value.
@@ -15,7 +31,7 @@ def pytest_sessionfinish(session: pytest.Session) -> None:
1531 """
1632 terminalreporter = session .config .pluginmanager .get_plugin ("terminalreporter" )
1733 if not isinstance (terminalreporter , TerminalReporter ):
18- raise TypeError
34+ raise TypeError # pragma: no cover
1935 req_passed = int (os .environ .get ("PYTEST_REQPASS" , "0" ))
2036 if req_passed and not session .config .option .collectonly :
2137 passed = 0
@@ -35,14 +51,26 @@ def pytest_collection_modifyitems(items: list[pytest.Item]) -> None:
3551 """Ensure testing fails if tests have duplicate names."""
3652 errors = []
3753 names = {}
54+ max_test_id_length = get_max_test_id_length ()
55+ test_id_regex = get_test_id_regex ()
3856 for item in items :
3957 base_name = item .name .split ("[" )[0 ]
4058 if base_name not in names :
4159 names [base_name ] = item .location
42- elif item .location [:2 ] != names [base_name ][:2 ]:
60+ elif item .location [:2 ] != names [base_name ][:2 ] and PYTEST_CHECK_TEST_DUPLICATE :
4361 error = f"Duplicate test name '{ base_name } ', found at { item .location [0 ]} :{ item .location [1 ]} and { names [base_name ][0 ]} :{ names [base_name ][1 ]} "
4462 if error not in errors :
4563 errors .append (error )
64+ if hasattr (item , "callspec" ):
65+ test_id = item .callspec .id
66+ if max_test_id_length and len (test_id ) > max_test_id_length :
67+ errors .append (
68+ f"{ item } has an id that looks above { max_test_id_length } characters." ,
69+ )
70+ elif test_id_regex and not test_id_regex .match (test_id ):
71+ errors .append (
72+ f"Test { item } has an id that does not match our safe pattern '{ test_id_regex .pattern } ' for use with a terminal." ,
73+ )
4674 if errors :
4775 msg = f"Failed run due to following issues being identified:\n { os .linesep .join (errors )} "
4876 raise pytest .UsageError (
0 commit comments