Skip to content

Add new testdirs ini option #823

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 11, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
or no tests were run at all (this is a partial fix for issue500).
Thanks Eric Siegerman.

- New `testdirs` ini option: list of directories to search for tests
when executing pytest from the root directory. This can be used
to speed up test collection when a project has well specified directories
for tests, being usually more practical than configuring norecursedirs for
all directories that do not contain tests.
Thanks to Adrian for idea (#694) and Bruno Oliveira for the PR.

- fix issue713: JUnit XML reports for doctest failures.
Thanks Punyashloka Biswal.

Expand Down
6 changes: 5 additions & 1 deletion _pytest/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,11 @@ def parse(self, args):
self.hook.pytest_cmdline_preparse(config=self, args=args)
args = self._parser.parse_setoption(args, self.option)
if not args:
args.append(os.getcwd())
cwd = os.getcwd()
if cwd == self.rootdir:
args = self.getini('testpaths')
if not args:
args = [cwd]
self.args = args
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor nit. os.getcwd() should be assigned to a var and then this var used instead of potentially calling it twice IMHO.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, done.


def addinivalue_line(self, name, line):
Expand Down
2 changes: 2 additions & 0 deletions _pytest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
def pytest_addoption(parser):
parser.addini("norecursedirs", "directory patterns to avoid for recursion",
type="args", default=['.*', 'CVS', '_darcs', '{arch}', '*.egg'])
parser.addini("testpaths", "directories to search for tests when no files or directories are given in the command line.",
type="args", default=[])
#parser.addini("dirpatterns",
# "patterns specifying possible locations of test files",
# type="linelist", default=["**/test_*.txt",
Expand Down
19 changes: 19 additions & 0 deletions doc/en/customize.txt
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,25 @@ Builtin configuration file options
This would tell ``pytest`` to not look into typical subversion or
sphinx-build directories or into any ``tmp`` prefixed directory.

.. confval:: testpaths

.. versionadded:: 2.8

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check if we can add .. versionadded:: here

Sets list of directories that should be searched for tests when
no specific directories or files are given in the command line when
executing pytest from the :ref:`rootdir <rootdir>` directory.
Useful when all project tests are in a known location to speed up
test collection and to avoid picking up undesired tests by accident.

.. code-block:: ini

# content of pytest.ini
[pytest]
testpaths = testing doc

This tells pytest to only look for tests in ``testing`` and ``doc``
directories when executing from the root directory.

.. confval:: python_files

One or more Glob-style file patterns determining which python files
Expand Down
7 changes: 5 additions & 2 deletions doc/en/goodpractises.txt
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,11 @@ Conventions for Python test discovery

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

* collection starts from the initial command line arguments
which may be directories, filenames or test ids.
* collection starts from paths specified in :confval:`testpaths` if configured,
otherwise from initial command line arguments which may be directories,
filenames or test ids. If :confval:`testpaths` is not configured and no
directories or files were given in the command line, start collection from
the current directory.
* recurse into directories, unless they match :confval:`norecursedirs`
* ``test_*.py`` or ``*_test.py`` files, imported by their `test package name`_.
* ``Test`` prefixed test classes (without an ``__init__`` method)
Expand Down
29 changes: 29 additions & 0 deletions testing/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,35 @@ def test_custom_norecursedirs(self, testdir):
rec = testdir.inline_run("xyz123/test_2.py")
rec.assertoutcome(failed=1)

def test_testpaths_ini(self, testdir, monkeypatch):
testdir.makeini("""
[pytest]
testpaths = gui uts
""")
tmpdir = testdir.tmpdir
tmpdir.ensure("env", "test_1.py").write("def test_env(): pass")
tmpdir.ensure("gui", "test_2.py").write("def test_gui(): pass")
tmpdir.ensure("uts", "test_3.py").write("def test_uts(): pass")

# executing from rootdir only tests from `testpaths` directories
# are collected
items, reprec = testdir.inline_genitems('-v')
assert [x.name for x in items] == ['test_gui', 'test_uts']

# check that explicitly passing directories in the command-line
# collects the tests
for dirname in ('env', 'gui', 'uts'):
items, reprec = testdir.inline_genitems(tmpdir.join(dirname))
assert [x.name for x in items] == ['test_%s' % dirname]

# changing cwd to each subdirectory and running pytest without
# arguments collects the tests in that directory normally
for dirname in ('env', 'gui', 'uts'):
monkeypatch.chdir(testdir.tmpdir.join(dirname))
items, reprec = testdir.inline_genitems()
assert [x.name for x in items] == ['test_%s' % dirname]


class TestCollectPluginHookRelay:
def test_pytest_collect_file(self, testdir):
wascalled = []
Expand Down