Skip to content

Commit 870f6fa

Browse files
committed
Add new testdirs ini option
Fix #694
1 parent e7374c3 commit 870f6fa

File tree

6 files changed

+67
-3
lines changed

6 files changed

+67
-3
lines changed

CHANGELOG

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
or no tests were run at all (this is a partial fix for issue500).
77
Thanks Eric Siegerman.
88

9+
- New `testdirs` ini option: list of directories to search for tests
10+
when executing pytest from the root directory. This can be used
11+
to speed up test collection when a project has well specified directories
12+
for tests, being usually more practical than configuring norecursedirs for
13+
all directories that do not contain tests.
14+
Thanks to Adrian for idea (#694) and Bruno Oliveira for the PR.
15+
916
- fix issue713: JUnit XML reports for doctest failures.
1017
Thanks Punyashloka Biswal.
1118

_pytest/config.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,11 @@ def parse(self, args):
917917
self.hook.pytest_cmdline_preparse(config=self, args=args)
918918
args = self._parser.parse_setoption(args, self.option)
919919
if not args:
920-
args.append(os.getcwd())
920+
cwd = os.getcwd()
921+
if cwd == self.rootdir:
922+
args = self.getini('testpaths')
923+
if not args:
924+
args = [cwd]
921925
self.args = args
922926

923927
def addinivalue_line(self, name, line):

_pytest/main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
def pytest_addoption(parser):
2626
parser.addini("norecursedirs", "directory patterns to avoid for recursion",
2727
type="args", default=['.*', 'CVS', '_darcs', '{arch}', '*.egg'])
28+
parser.addini("testpaths", "directories to search for tests when no files or directories are given in the command line.",
29+
type="args", default=[])
2830
#parser.addini("dirpatterns",
2931
# "patterns specifying possible locations of test files",
3032
# type="linelist", default=["**/test_*.txt",

doc/en/customize.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,25 @@ Builtin configuration file options
157157
This would tell ``pytest`` to not look into typical subversion or
158158
sphinx-build directories or into any ``tmp`` prefixed directory.
159159

160+
.. confval:: testpaths
161+
162+
.. versionadded:: 2.8
163+
164+
Sets list of directories that should be searched for tests when
165+
no specific directories or files are given in the command line when
166+
executing pytest from the :ref:`rootdir <rootdir>` directory.
167+
Useful when all project tests are in a known location to speed up
168+
test collection and to avoid picking up undesired tests by accident.
169+
170+
.. code-block:: ini
171+
172+
# content of pytest.ini
173+
[pytest]
174+
testpaths = testing doc
175+
176+
This tells pytest to only look for tests in ``testing`` and ``doc``
177+
directories when executing from the root directory.
178+
160179
.. confval:: python_files
161180

162181
One or more Glob-style file patterns determining which python files

doc/en/goodpractises.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,11 @@ Conventions for Python test discovery
282282

283283
``pytest`` implements the following standard test discovery:
284284

285-
* collection starts from the initial command line arguments
286-
which may be directories, filenames or test ids.
285+
* collection starts from paths specified in :confval:`testpaths` if configured,
286+
otherwise from initial command line arguments which may be directories,
287+
filenames or test ids. If :confval:`testpaths` is not configured and no
288+
directories or files were given in the command line, start collection from
289+
the current directory.
287290
* recurse into directories, unless they match :confval:`norecursedirs`
288291
* ``test_*.py`` or ``*_test.py`` files, imported by their `test package name`_.
289292
* ``Test`` prefixed test classes (without an ``__init__`` method)

testing/test_collection.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,35 @@ def test_custom_norecursedirs(self, testdir):
116116
rec = testdir.inline_run("xyz123/test_2.py")
117117
rec.assertoutcome(failed=1)
118118

119+
def test_testpaths_ini(self, testdir, monkeypatch):
120+
testdir.makeini("""
121+
[pytest]
122+
testpaths = gui uts
123+
""")
124+
tmpdir = testdir.tmpdir
125+
tmpdir.ensure("env", "test_1.py").write("def test_env(): pass")
126+
tmpdir.ensure("gui", "test_2.py").write("def test_gui(): pass")
127+
tmpdir.ensure("uts", "test_3.py").write("def test_uts(): pass")
128+
129+
# executing from rootdir only tests from `testpaths` directories
130+
# are collected
131+
items, reprec = testdir.inline_genitems('-v')
132+
assert [x.name for x in items] == ['test_gui', 'test_uts']
133+
134+
# check that explicitly passing directories in the command-line
135+
# collects the tests
136+
for dirname in ('env', 'gui', 'uts'):
137+
items, reprec = testdir.inline_genitems(tmpdir.join(dirname))
138+
assert [x.name for x in items] == ['test_%s' % dirname]
139+
140+
# changing cwd to each subdirectory and running pytest without
141+
# arguments collects the tests in that directory normally
142+
for dirname in ('env', 'gui', 'uts'):
143+
monkeypatch.chdir(testdir.tmpdir.join(dirname))
144+
items, reprec = testdir.inline_genitems()
145+
assert [x.name for x in items] == ['test_%s' % dirname]
146+
147+
119148
class TestCollectPluginHookRelay:
120149
def test_pytest_collect_file(self, testdir):
121150
wascalled = []

0 commit comments

Comments
 (0)