/
niceSOFT
/
python3-pytest
Обзор
Документация
Войти
/
niceSOFT
/
python3-pytest
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
doc/en/example/pythoncollection.rst
344 строки
10 KB
Ran Benita
Merge pull request #14627 from pytest-dev/release-9.1.1
19 июн 2026, 14:00
19 июн 2026, 14:00
4c942a4
Код
Авторство
О чём код?
Changing standard (Python) test discovery =============================================== Ignore paths during test collection ----------------------------------- You can easily ignore certain test directories and modules during collection by passing the :option:`--ignore=path` option on the cli. ``pytest`` allows multiple ``--ignore`` options. Example: .. code-block:: text tests/ |-- example | |-- test_example_01.py | |-- test_example_02.py | '-- test_example_03.py |-- foobar | |-- test_foobar_01.py | |-- test_foobar_02.py | '-- test_foobar_03.py '-- hello '-- world |-- test_world_01.py |-- test_world_02.py '-- test_world_03.py Now if you invoke ``pytest`` with ``--ignore=tests/foobar/test_foobar_03.py --ignore=tests/hello/``, you will see that ``pytest`` only collects test-modules, which do not match the patterns specified: .. code-block:: pytest =========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-5.x.y, py-1.x.y, pluggy-0.x.y rootdir: $REGENDOC_TMPDIR, inifile: collected 5 items tests/example/test_example_01.py . [ 20%] tests/example/test_example_02.py . [ 40%] tests/example/test_example_03.py . [ 60%] tests/foobar/test_foobar_01.py . [ 80%] tests/foobar/test_foobar_02.py . [100%] ========================= 5 passed in 0.02 seconds ========================= The :option:`--ignore-glob` option allows to ignore test file paths based on Unix shell-style wildcards. If you want to exclude test-modules that end with ``_01.py``, execute ``pytest`` with :option:`--ignore-glob='*_01.py'`. Deselect tests during test collection ------------------------------------- Tests can individually be deselected during collection by passing the :option:`--deselect=item` option. For example, say ``tests/foobar/test_foobar_01.py`` contains ``test_a`` and ``test_b``. You can run all of the tests within ``tests/`` *except* for ``tests/foobar/test_foobar_01.py::test_a`` by invoking ``pytest`` with ``--deselect=tests/foobar/test_foobar_01.py::test_a``. ``pytest`` allows multiple ``--deselect`` options. .. _duplicate-paths: Keeping duplicate paths specified from command line ---------------------------------------------------- Default behavior of ``pytest`` is to ignore duplicate paths specified from the command line. Example: .. code-block:: pytest pytest path_a path_a ... collected 1 item ... Just collect tests once. To collect duplicate tests, use the :option:`--keep-duplicates` option on the cli. Example: .. code-block:: pytest pytest --keep-duplicates path_a path_a ... collected 2 items ... Changing directory recursion ----------------------------------------------------- You can set the :confval:`norecursedirs` option in a configuration file: .. code-block:: toml # content of pytest.toml [pytest] norecursedirs = [".svn", "_build", "tmp*"] This would tell ``pytest`` to not recurse into typical subversion or sphinx-build directories or into any ``tmp`` prefixed directory. .. _`change naming conventions`: Changing naming conventions ----------------------------------------------------- You can configure different naming conventions by setting the :confval:`python_files`, :confval:`python_classes` and :confval:`python_functions` in your :ref:`configuration file <config file formats>`. Here is an example: .. code-block:: toml # content of pytest.toml # Example 1: have pytest look for "check" instead of "test" [pytest] python_files = ["check_*.py"] python_classes = ["Check"] python_functions = ["*_check"] This would make ``pytest`` look for tests in files that match the ``check_* .py`` glob-pattern, ``Check`` prefixes in classes, and functions and methods that match ``*_check``. For example, if we have: .. code-block:: python # content of check_myapp.py class CheckMyApp: def simple_check(self): pass def complex_check(self): pass The test collection would look like this: .. code-block:: pytest $ pytest --collect-only =========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-9.x.y, pluggy-1.x.y rootdir: /home/sweet/project configfile: pytest.toml collected 2 items <Dir pythoncollection.rst-216> <Module check_myapp.py> <Class CheckMyApp> <Function simple_check> <Function complex_check> ======================== 2 tests collected in 0.12s ======================== You can check for multiple glob patterns by adding a space between the patterns: .. code-block:: toml # content of pytest.toml # Example 2: have pytest look for files with "test" and "example" [pytest] python_files = ["test_*.py", "example_*.py"] .. note:: the ``python_functions`` and ``python_classes`` options have no effect for ``unittest.TestCase`` test discovery because pytest delegates discovery of test case methods to unittest code. Interpreting cmdline arguments as Python packages ----------------------------------------------------- You can use the :option:`--pyargs` option to make ``pytest`` try interpreting arguments as python package names, deriving their file system path and then running the test. For example if you have unittest2 installed you can type: .. code-block:: bash pytest --pyargs unittest2.test.test_skipping -q which would run the respective test module. Like with other options, through a configuration file and the :confval:`addopts` option you can make this change more permanently: .. code-block:: toml # content of pytest.toml [pytest] addopts = ["--pyargs"] Now a simple invocation of ``pytest NAME`` will check if NAME exists as an importable package/module and otherwise treat it as a filesystem path. Finding out what is collected ----------------------------------------------- You can always peek at the collection tree without running tests like this: .. code-block:: pytest . $ pytest --collect-only pythoncollection.py =========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-9.x.y, pluggy-1.x.y rootdir: /home/sweet/project configfile: pytest.toml collected 3 items <Dir pythoncollection.rst-216> <Dir CWD> <Module pythoncollection.py> <Function test_function> <Class TestClass> <Function test_method> <Function test_anothermethod> ======================== 3 tests collected in 0.12s ======================== .. _customizing-test-collection: Customizing test collection --------------------------- .. regendoc:wipe You can easily instruct ``pytest`` to discover tests from every Python file: .. code-block:: toml # content of pytest.toml [pytest] python_files = ["*.py"] However, many projects will have a ``setup.py`` which they don't want to be imported. Moreover, there may be files only importable by a specific python version. For such cases you can dynamically define files to be ignored by listing them in a ``conftest.py`` file: .. code-block:: python # content of conftest.py import sys collect_ignore = ["setup.py"] if sys.version_info[0] > 2: collect_ignore.append("pkg/module_py2.py") and then if you have a module file like this: .. code-block:: python # content of pkg/module_py2.py def test_only_on_python2(): try: assert 0 except Exception, e: pass and a ``setup.py`` dummy file like this: .. code-block:: python # content of setup.py 0 / 0 # will raise exception if imported If you run with a Python 2 interpreter then you will find the one test and will leave out the ``setup.py`` file: .. code-block:: pytest #$ pytest --collect-only ====== test session starts ====== platform linux2 -- Python 2.7.10, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini collected 1 items <Module 'pkg/module_py2.py'> <Function 'test_only_on_python2'> ====== 1 tests found in 0.04 seconds ====== If you run with a Python 3 interpreter both the one test and the ``setup.py`` file will be left out: .. code-block:: pytest $ pytest --collect-only =========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-9.x.y, pluggy-1.x.y rootdir: /home/sweet/project configfile: pytest.toml collected 0 items ======================= no tests collected in 0.12s ======================== It's also possible to ignore files based on Unix shell-style wildcards by adding patterns to :globalvar:`collect_ignore_glob`. The following example ``conftest.py`` ignores the file ``setup.py`` and in addition all files that end with ``*_py2.py`` when executed with a Python 3 interpreter: .. code-block:: python # content of conftest.py import sys collect_ignore = ["setup.py"] if sys.version_info[0] > 2: collect_ignore_glob = ["*_py2.py"] Since Pytest 2.6, users can prevent pytest from discovering classes that start with ``Test`` by setting a boolean ``__test__`` attribute to ``False``. .. code-block:: python # Will not be discovered as a test class TestClass: __test__ = False .. note:: If you are working with abstract test classes and want to avoid manually setting the ``__test__`` attribute for subclasses, you can use a mixin class to handle this automatically. For example: .. code-block:: python # Mixin to handle abstract test classes class NotATest: def __init_subclass__(cls): cls.__test__ = NotATest not in cls.__bases__ # Abstract test class class AbstractTest(NotATest): pass # Subclass that will be collected as a test class RealTest(AbstractTest): def test_example(self): assert 1 + 1 == 2 This approach ensures that subclasses of abstract test classes are automatically collected without needing to explicitly set the ``__test__`` attribute.