2010-11-06 06:37:25 +08:00
|
|
|
Changing standard (Python) test discovery
|
|
|
|
===============================================
|
|
|
|
|
2015-11-04 21:49:02 +08:00
|
|
|
Ignore paths during test collection
|
|
|
|
-----------------------------------
|
|
|
|
|
|
|
|
You can easily ignore certain test directories and modules during collection
|
|
|
|
by passing the ``--ignore=path`` option on the cli. ``pytest`` allows multiple
|
2019-02-13 23:08:49 +08:00
|
|
|
``--ignore`` options. Example:
|
|
|
|
|
|
|
|
.. code-block:: text
|
2015-11-04 22:00:37 +08:00
|
|
|
|
|
|
|
tests/
|
2016-04-14 05:16:41 +08:00
|
|
|
|-- 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
|
2015-11-04 22:00:37 +08:00
|
|
|
|
2015-11-05 06:45:29 +08:00
|
|
|
Now if you invoke ``pytest`` with ``--ignore=tests/foobar/test_foobar_03.py --ignore=tests/hello/``,
|
2018-11-24 13:41:22 +08:00
|
|
|
you will see that ``pytest`` only collects test-modules, which do not match the patterns specified:
|
2015-11-04 22:30:11 +08:00
|
|
|
|
2018-11-24 13:41:22 +08:00
|
|
|
.. code-block:: pytest
|
|
|
|
|
|
|
|
=========================== test session starts ============================
|
2019-08-08 11:49:30 +08:00
|
|
|
platform linux -- Python 3.x.y, pytest-5.x.y, py-1.x.y, pluggy-0.x.y
|
2015-11-04 22:30:11 +08:00
|
|
|
rootdir: $REGENDOC_TMPDIR, inifile:
|
|
|
|
collected 5 items
|
|
|
|
|
2018-11-24 13:41:22 +08:00
|
|
|
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%]
|
2015-11-04 22:30:11 +08:00
|
|
|
|
2018-11-24 13:41:22 +08:00
|
|
|
========================= 5 passed in 0.02 seconds =========================
|
2015-11-04 22:30:11 +08:00
|
|
|
|
2019-02-06 00:19:24 +08:00
|
|
|
The ``--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 ``--ignore-glob='*_01.py'``.
|
|
|
|
|
2018-02-10 07:44:03 +08:00
|
|
|
Deselect tests during test collection
|
|
|
|
-------------------------------------
|
|
|
|
|
|
|
|
Tests can individually be deselected during collection by passing the ``--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.
|
2015-11-04 21:49:02 +08:00
|
|
|
|
2016-07-25 18:40:57 +08:00
|
|
|
Keeping duplicate paths specified from command line
|
|
|
|
----------------------------------------------------
|
|
|
|
|
|
|
|
Default behavior of ``pytest`` is to ignore duplicate paths specified from the command line.
|
2019-02-13 23:08:49 +08:00
|
|
|
Example:
|
|
|
|
|
|
|
|
.. code-block:: pytest
|
2016-07-25 18:40:57 +08:00
|
|
|
|
2018-05-13 18:09:47 +08:00
|
|
|
pytest path_a path_a
|
2016-07-25 18:40:57 +08:00
|
|
|
|
|
|
|
...
|
|
|
|
collected 1 item
|
|
|
|
...
|
|
|
|
|
|
|
|
Just collect tests once.
|
|
|
|
|
|
|
|
To collect duplicate tests, use the ``--keep-duplicates`` option on the cli.
|
2019-02-13 23:08:49 +08:00
|
|
|
Example:
|
2016-07-25 18:40:57 +08:00
|
|
|
|
2019-02-13 23:08:49 +08:00
|
|
|
.. code-block:: pytest
|
2016-07-25 18:40:57 +08:00
|
|
|
|
2018-05-13 18:09:47 +08:00
|
|
|
pytest --keep-duplicates path_a path_a
|
2016-07-25 18:40:57 +08:00
|
|
|
|
|
|
|
...
|
|
|
|
collected 2 items
|
|
|
|
...
|
|
|
|
|
|
|
|
As the collector just works on directories, if you specify twice a single test file, ``pytest`` will
|
|
|
|
still collect it twice, no matter if the ``--keep-duplicates`` is not specified.
|
2019-02-13 23:08:49 +08:00
|
|
|
Example:
|
|
|
|
|
|
|
|
.. code-block:: pytest
|
2016-07-25 18:40:57 +08:00
|
|
|
|
2018-05-13 18:09:47 +08:00
|
|
|
pytest test_a.py test_a.py
|
2016-07-25 18:40:57 +08:00
|
|
|
|
|
|
|
...
|
|
|
|
collected 2 items
|
|
|
|
...
|
|
|
|
|
|
|
|
|
2011-09-06 17:43:42 +08:00
|
|
|
Changing directory recursion
|
2010-11-06 06:37:25 +08:00
|
|
|
-----------------------------------------------------
|
|
|
|
|
2019-02-13 23:08:49 +08:00
|
|
|
You can set the :confval:`norecursedirs` option in an ini-file, for example your ``pytest.ini`` in the project root directory:
|
|
|
|
|
|
|
|
.. code-block:: ini
|
2010-11-06 06:37:25 +08:00
|
|
|
|
2016-08-17 08:30:07 +08:00
|
|
|
# content of pytest.ini
|
2010-11-06 06:37:25 +08:00
|
|
|
[pytest]
|
|
|
|
norecursedirs = .svn _build tmp*
|
|
|
|
|
2014-01-18 19:31:33 +08:00
|
|
|
This would tell ``pytest`` to not recurse into typical subversion or sphinx-build directories or into any ``tmp`` prefixed directory.
|
2010-11-06 06:37:25 +08:00
|
|
|
|
2010-11-25 05:01:04 +08:00
|
|
|
.. _`change naming conventions`:
|
|
|
|
|
2011-09-06 17:43:42 +08:00
|
|
|
Changing naming conventions
|
2010-11-25 05:01:04 +08:00
|
|
|
-----------------------------------------------------
|
|
|
|
|
|
|
|
You can configure different naming conventions by setting
|
2010-11-25 19:11:10 +08:00
|
|
|
the :confval:`python_files`, :confval:`python_classes` and
|
2020-06-08 21:03:10 +08:00
|
|
|
:confval:`python_functions` in your :ref:`configuration file <config file formats>`.
|
2019-02-13 23:08:49 +08:00
|
|
|
Here is an example:
|
|
|
|
|
|
|
|
.. code-block:: ini
|
2010-11-25 05:01:04 +08:00
|
|
|
|
2016-08-17 08:30:07 +08:00
|
|
|
# content of pytest.ini
|
2018-08-26 20:58:47 +08:00
|
|
|
# Example 1: have pytest look for "check" instead of "test"
|
2010-11-25 05:01:04 +08:00
|
|
|
[pytest]
|
2018-08-22 22:22:30 +08:00
|
|
|
python_files = check_*.py
|
|
|
|
python_classes = Check
|
|
|
|
python_functions = *_check
|
2010-11-25 05:01:04 +08:00
|
|
|
|
2014-10-17 06:27:10 +08:00
|
|
|
This would make ``pytest`` look for tests in files that match the ``check_*
|
|
|
|
.py`` glob-pattern, ``Check`` prefixes in classes, and functions and methods
|
2019-08-07 07:20:06 +08:00
|
|
|
that match ``*_check``. For example, if we have:
|
2010-11-25 05:01:04 +08:00
|
|
|
|
2019-08-07 04:25:54 +08:00
|
|
|
.. code-block:: python
|
|
|
|
|
2010-11-25 05:01:04 +08:00
|
|
|
# content of check_myapp.py
|
2017-02-17 02:41:51 +08:00
|
|
|
class CheckMyApp:
|
2014-10-17 06:27:10 +08:00
|
|
|
def simple_check(self):
|
2010-11-25 05:01:04 +08:00
|
|
|
pass
|
2019-08-07 04:34:58 +08:00
|
|
|
|
2014-10-17 06:27:10 +08:00
|
|
|
def complex_check(self):
|
2010-11-25 05:01:04 +08:00
|
|
|
pass
|
|
|
|
|
2018-11-24 13:41:22 +08:00
|
|
|
The test collection would look like this:
|
|
|
|
|
|
|
|
.. code-block:: pytest
|
2010-11-25 05:01:04 +08:00
|
|
|
|
2016-06-21 22:16:57 +08:00
|
|
|
$ pytest --collect-only
|
2019-01-06 03:19:40 +08:00
|
|
|
=========================== test session starts ============================
|
2024-01-02 16:58:20 +08:00
|
|
|
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
|
2023-03-17 16:32:08 +08:00
|
|
|
rootdir: /home/sweet/project
|
|
|
|
configfile: pytest.ini
|
2018-08-26 20:58:47 +08:00
|
|
|
collected 2 items
|
2020-07-09 05:51:01 +08:00
|
|
|
|
2024-02-25 06:24:32 +08:00
|
|
|
<Dir pythoncollection.rst-195>
|
2024-01-02 16:58:20 +08:00
|
|
|
<Module check_myapp.py>
|
|
|
|
<Class CheckMyApp>
|
|
|
|
<Function simple_check>
|
|
|
|
<Function complex_check>
|
2018-05-18 16:19:46 +08:00
|
|
|
|
2020-12-13 05:21:28 +08:00
|
|
|
======================== 2 tests collected in 0.12s ========================
|
2010-11-25 05:01:04 +08:00
|
|
|
|
2019-02-13 23:08:49 +08:00
|
|
|
You can check for multiple glob patterns by adding a space between the patterns:
|
|
|
|
|
|
|
|
.. code-block:: ini
|
2018-08-22 21:37:35 +08:00
|
|
|
|
|
|
|
# Example 2: have pytest look for files with "test" and "example"
|
2020-06-08 21:03:10 +08:00
|
|
|
# content of pytest.ini
|
2018-08-22 21:37:35 +08:00
|
|
|
[pytest]
|
2018-08-22 22:22:30 +08:00
|
|
|
python_files = test_*.py example_*.py
|
2018-08-22 21:37:35 +08:00
|
|
|
|
2013-11-22 20:53:43 +08:00
|
|
|
.. note::
|
2014-01-18 19:31:33 +08:00
|
|
|
|
2014-10-17 06:27:10 +08:00
|
|
|
the ``python_functions`` and ``python_classes`` options has no effect
|
2013-11-22 20:53:43 +08:00
|
|
|
for ``unittest.TestCase`` test discovery because pytest delegates
|
2018-08-22 22:22:30 +08:00
|
|
|
discovery of test case methods to unittest code.
|
2013-11-22 20:53:43 +08:00
|
|
|
|
2011-09-06 17:43:42 +08:00
|
|
|
Interpreting cmdline arguments as Python packages
|
2010-11-07 07:22:16 +08:00
|
|
|
-----------------------------------------------------
|
|
|
|
|
2014-01-18 19:31:33 +08:00
|
|
|
You can use the ``--pyargs`` option to make ``pytest`` try
|
2010-11-07 07:22:16 +08:00
|
|
|
interpreting arguments as python package names, deriving
|
2010-11-25 05:01:04 +08:00
|
|
|
their file system path and then running the test. For
|
2019-02-13 23:08:49 +08:00
|
|
|
example if you have unittest2 installed you can type:
|
|
|
|
|
|
|
|
.. code-block:: bash
|
2010-11-25 05:01:04 +08:00
|
|
|
|
2016-06-21 22:16:57 +08:00
|
|
|
pytest --pyargs unittest2.test.test_skipping -q
|
2010-11-25 05:01:04 +08:00
|
|
|
|
2010-11-25 19:11:10 +08:00
|
|
|
which would run the respective test module. Like with
|
2010-11-25 05:01:04 +08:00
|
|
|
other options, through an ini-file and the :confval:`addopts` option you
|
2019-02-13 23:08:49 +08:00
|
|
|
can make this change more permanently:
|
|
|
|
|
|
|
|
.. code-block:: ini
|
2010-11-07 07:22:16 +08:00
|
|
|
|
2010-11-21 04:35:55 +08:00
|
|
|
# content of pytest.ini
|
2010-11-07 07:22:16 +08:00
|
|
|
[pytest]
|
|
|
|
addopts = --pyargs
|
2010-11-06 06:37:25 +08:00
|
|
|
|
2016-06-21 22:16:57 +08:00
|
|
|
Now a simple invocation of ``pytest NAME`` will check
|
2010-11-25 05:01:04 +08:00
|
|
|
if NAME exists as an importable package/module and otherwise
|
|
|
|
treat it as a filesystem path.
|
|
|
|
|
2011-09-06 17:43:42 +08:00
|
|
|
Finding out what is collected
|
2010-11-06 06:37:25 +08:00
|
|
|
-----------------------------------------------
|
|
|
|
|
2018-11-24 13:41:22 +08:00
|
|
|
You can always peek at the collection tree without running tests like this:
|
|
|
|
|
|
|
|
.. code-block:: pytest
|
2010-11-06 06:37:25 +08:00
|
|
|
|
2016-06-21 22:16:57 +08:00
|
|
|
. $ pytest --collect-only pythoncollection.py
|
2019-01-06 03:19:40 +08:00
|
|
|
=========================== test session starts ============================
|
2024-01-02 16:58:20 +08:00
|
|
|
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
|
2023-03-17 16:32:08 +08:00
|
|
|
rootdir: /home/sweet/project
|
|
|
|
configfile: pytest.ini
|
2017-05-13 04:51:20 +08:00
|
|
|
collected 3 items
|
2020-07-09 05:51:01 +08:00
|
|
|
|
2024-02-25 06:24:32 +08:00
|
|
|
<Dir pythoncollection.rst-195>
|
2024-01-02 16:58:20 +08:00
|
|
|
<Dir CWD>
|
|
|
|
<Module pythoncollection.py>
|
|
|
|
<Function test_function>
|
|
|
|
<Class TestClass>
|
|
|
|
<Function test_method>
|
|
|
|
<Function test_anothermethod>
|
2018-05-18 16:19:46 +08:00
|
|
|
|
2020-12-13 05:21:28 +08:00
|
|
|
======================== 3 tests collected in 0.12s ========================
|
2012-06-07 18:39:53 +08:00
|
|
|
|
2017-10-27 00:14:29 +08:00
|
|
|
.. _customizing-test-collection:
|
2012-06-07 18:39:53 +08:00
|
|
|
|
2017-10-27 00:14:29 +08:00
|
|
|
Customizing test collection
|
|
|
|
---------------------------
|
2012-06-07 18:39:53 +08:00
|
|
|
|
2017-10-27 00:14:29 +08:00
|
|
|
.. regendoc:wipe
|
2012-06-07 18:39:53 +08:00
|
|
|
|
2019-02-13 23:08:49 +08:00
|
|
|
You can easily instruct ``pytest`` to discover tests from every Python file:
|
|
|
|
|
|
|
|
.. code-block:: ini
|
2012-06-07 18:39:53 +08:00
|
|
|
|
|
|
|
# content of pytest.ini
|
|
|
|
[pytest]
|
|
|
|
python_files = *.py
|
|
|
|
|
2017-10-27 00:14:29 +08:00
|
|
|
However, many projects will have a ``setup.py`` which they don't want to be
|
|
|
|
imported. Moreover, there may files only importable by a specific python
|
|
|
|
version. For such cases you can dynamically define files to be ignored by
|
2019-08-07 07:20:06 +08:00
|
|
|
listing them in a ``conftest.py`` file:
|
2012-06-07 18:39:53 +08:00
|
|
|
|
2019-08-07 04:25:54 +08:00
|
|
|
.. code-block:: python
|
|
|
|
|
2012-06-07 18:39:53 +08:00
|
|
|
# content of conftest.py
|
|
|
|
import sys
|
|
|
|
|
|
|
|
collect_ignore = ["setup.py"]
|
|
|
|
if sys.version_info[0] > 2:
|
|
|
|
collect_ignore.append("pkg/module_py2.py")
|
|
|
|
|
2019-08-07 07:20:06 +08:00
|
|
|
and then if you have a module file like this:
|
2012-06-07 18:39:53 +08:00
|
|
|
|
2019-08-07 04:25:54 +08:00
|
|
|
.. code-block:: python
|
|
|
|
|
2012-06-07 18:39:53 +08:00
|
|
|
# content of pkg/module_py2.py
|
|
|
|
def test_only_on_python2():
|
|
|
|
try:
|
|
|
|
assert 0
|
|
|
|
except Exception, e:
|
|
|
|
pass
|
|
|
|
|
2019-08-07 07:20:06 +08:00
|
|
|
and a ``setup.py`` dummy file like this:
|
2012-06-07 18:39:53 +08:00
|
|
|
|
2019-08-07 04:25:54 +08:00
|
|
|
.. code-block:: python
|
|
|
|
|
2012-06-07 18:39:53 +08:00
|
|
|
# content of setup.py
|
2015-11-28 14:46:45 +08:00
|
|
|
0 / 0 # will raise exception if imported
|
2012-06-07 18:39:53 +08:00
|
|
|
|
2017-10-27 00:14:29 +08:00
|
|
|
If you run with a Python 2 interpreter then you will find the one test and will
|
2018-11-24 13:41:22 +08:00
|
|
|
leave out the ``setup.py`` file:
|
|
|
|
|
|
|
|
.. code-block:: pytest
|
2014-01-18 19:31:33 +08:00
|
|
|
|
2016-06-21 22:16:57 +08:00
|
|
|
#$ pytest --collect-only
|
2016-03-20 20:18:17 +08:00
|
|
|
====== 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'>
|
|
|
|
|
2020-11-08 22:45:10 +08:00
|
|
|
====== 1 tests found in 0.04 seconds ======
|
2016-03-20 20:18:17 +08:00
|
|
|
|
2017-10-27 00:14:29 +08:00
|
|
|
If you run with a Python 3 interpreter both the one test and the ``setup.py``
|
2018-11-24 13:41:22 +08:00
|
|
|
file will be left out:
|
|
|
|
|
|
|
|
.. code-block:: pytest
|
2016-03-20 20:18:17 +08:00
|
|
|
|
2016-06-21 22:16:57 +08:00
|
|
|
$ pytest --collect-only
|
2019-01-06 03:19:40 +08:00
|
|
|
=========================== test session starts ============================
|
2024-01-02 16:58:20 +08:00
|
|
|
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
|
2023-03-17 16:32:08 +08:00
|
|
|
rootdir: /home/sweet/project
|
|
|
|
configfile: pytest.ini
|
2015-09-22 22:52:35 +08:00
|
|
|
collected 0 items
|
2018-05-18 16:19:46 +08:00
|
|
|
|
2020-12-13 05:21:28 +08:00
|
|
|
======================= no tests collected in 0.12s ========================
|
2019-02-06 17:50:46 +08:00
|
|
|
|
|
|
|
It's also possible to ignore files based on Unix shell-style wildcards by adding
|
2020-07-10 20:50:03 +08:00
|
|
|
patterns to :globalvar:`collect_ignore_glob`.
|
2019-02-06 17:50:46 +08:00
|
|
|
|
|
|
|
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
|
2019-08-07 07:20:06 +08:00
|
|
|
interpreter:
|
2019-02-06 17:50:46 +08:00
|
|
|
|
2019-08-07 04:25:54 +08:00
|
|
|
.. code-block:: python
|
|
|
|
|
2019-02-06 17:50:46 +08:00
|
|
|
# content of conftest.py
|
|
|
|
import sys
|
|
|
|
|
|
|
|
collect_ignore = ["setup.py"]
|
|
|
|
if sys.version_info[0] > 2:
|
|
|
|
collect_ignore_glob = ["*_py2.py"]
|
2020-09-09 21:33:39 +08:00
|
|
|
|
|
|
|
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
|