Skip to content

Commit a09affe

Browse files
committed
Add new testdirs ini option
Fix #694
1 parent ae4c8b8 commit a09affe

File tree

6 files changed

+67
-4
lines changed

6 files changed

+67
-4
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: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,10 @@ 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+
if os.getcwd() == self.rootdir:
921+
args = self.getini('testpaths')
922+
if not args:
923+
args = [os.getcwd()]
921924
self.args = args
922925

923926
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: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,32 @@ Builtin configuration file options
144144
Setting a ``norecursedirs`` replaces the default. Here is an example of
145145
how to avoid certain directories::
146146

147-
# content of setup.cfg
147+
# content of pytest.ini
148148
[pytest]
149149
norecursedirs = .svn _build tmp*
150150

151151
This would tell ``pytest`` to not look into typical subversion or
152152
sphinx-build directories or into any ``tmp`` prefixed directory.
153153

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

156175
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)