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
2015-11-04 22:00:37 +08:00
`` --ignore `` options. Example::
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/ `` ,
you will see that `` pytest `` only collects test-modules, which do not match the patterns specified::
2015-11-04 22:30:11 +08:00
========= test session starts ==========
platform darwin -- Python 2.7.10, pytest-2.8.2, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 5 items
tests/example/test_example_01.py .
tests/example/test_example_02.py .
tests/example/test_example_03.py .
tests/foobar/test_foobar_01.py .
tests/foobar/test_foobar_02.py .
======= 5 passed in 0.02 seconds =======
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.
Example::
py.test path_a path_a
...
collected 1 item
...
Just collect tests once.
To collect duplicate tests, use the `` --keep-duplicates `` option on the cli.
Example::
py.test --keep-duplicates path_a path_a
...
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.
Example::
py.test test_a.py test_a.py
...
collected 2 items
...
2011-09-06 17:43:42 +08:00
Changing directory recursion
2010-11-06 06:37:25 +08:00
-----------------------------------------------------
2016-08-17 08:30:07 +08:00
You can set the :confval: `norecursedirs` option in an ini-file, for example your `` pytest.ini `` in the project root directory::
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
:confval: `python_functions` configuration options. Example::
2010-11-25 05:01:04 +08:00
2016-08-17 08:30:07 +08:00
# content of pytest.ini
2017-01-01 01:54:47 +08:00
# can also be defined in tox.ini or setup.cfg file, although the section
2016-08-17 08:30:07 +08:00
# name in setup.cfg files should be "tool:pytest"
2010-11-25 05:01:04 +08:00
[pytest]
python_files=check_*.py
python_classes=Check
2014-10-17 06:27:10 +08:00
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
that match `` *_check `` . For example, if we have::
2010-11-25 05:01:04 +08:00
# content of check_myapp.py
2017-02-17 02:41:51 +08:00
class CheckMyApp(object):
2014-10-17 06:27:10 +08:00
def simple_check(self):
2010-11-25 05:01:04 +08:00
pass
2014-10-17 06:27:10 +08:00
def complex_check(self):
2010-11-25 05:01:04 +08:00
pass
then the test collection looks like this::
2016-06-21 22:16:57 +08:00
$ pytest --collect-only
2015-06-07 05:30:49 +08:00
======= test session starts ========
2017-05-13 04:17:40 +08:00
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y
2016-08-18 20:27:16 +08:00
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
2012-10-07 19:06:17 +08:00
collected 2 items
2010-11-25 05:01:04 +08:00
<Module 'check_myapp.py'>
<Class 'CheckMyApp'>
<Instance '()'>
2014-10-17 06:27:10 +08:00
<Function 'simple_check'>
<Function 'complex_check'>
2014-01-29 20:47:11 +08:00
2015-12-06 23:14:23 +08:00
======= no tests ran in 0.12 seconds ========
2010-11-25 05:01:04 +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
detection of test case methods to unittest code.
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
example if you have unittest2 installed you can type::
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
can make this change more permanently::
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
-----------------------------------------------
You can always peek at the collection tree without running tests like this::
2016-06-21 22:16:57 +08:00
. $ pytest --collect-only pythoncollection.py
2017-05-13 04:51:20 +08:00
======= test session starts ========
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 3 items
<Module 'CWD/pythoncollection.py'>
<Function 'test_function'>
<Class 'TestClass'>
<Instance '()'>
<Function 'test_method'>
<Function 'test_anothermethod'>
2014-01-29 20:47:11 +08:00
2017-05-13 04:51:20 +08:00
======= no tests ran in 0.12 seconds ========
2012-06-07 18:39:53 +08:00
2012-06-11 22:24:42 +08:00
customizing test collection to find all .py files
2012-06-07 18:39:53 +08:00
---------------------------------------------------------
.. regendoc:wipe
2014-01-18 19:31:33 +08:00
You can easily instruct `` pytest `` to discover tests from every python file::
2012-06-07 18:39:53 +08:00
# content of pytest.ini
[pytest]
python_files = *.py
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.
2014-01-18 19:31:33 +08:00
For such cases you can dynamically define files to be ignored by listing
them in a `` conftest.py `` file::
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")
And then if you have a module file like this::
# 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::
# 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
2016-03-20 20:18:17 +08:00
then a pytest run on Python2 will find the one test and will leave out the
setup.py file::
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'>
====== no tests ran in 0.04 seconds ======
If you run with a Python3 interpreter both the one test and the setup.py file
will be left out::
2016-06-21 22:16:57 +08:00
$ pytest --collect-only
2016-05-31 17:15:57 +08:00
======= test session starts ========
2017-05-13 04:17:40 +08:00
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y
2015-06-07 05:30:49 +08:00
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
2015-09-22 22:52:35 +08:00
collected 0 items
2016-05-31 17:15:57 +08:00
======= no tests ran in 0.12 seconds ========