From 3d24485caef6631c43f4964d43a15dc05a67a74a Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Wed, 19 Jul 2017 21:11:17 -0300 Subject: [PATCH 1/3] Clarify PYTHONPATH changes and ``rootdir`` roles - Also minor adjustments in the docs (wording, formatting, links, etc). Fix #2589 --- _pytest/config.py | 1 - doc/en/cache.rst | 2 ++ doc/en/contents.rst | 3 +- doc/en/customize.rst | 30 +++++++++++----- doc/en/example/index.rst | 4 +-- doc/en/nose.rst | 2 +- doc/en/pythonpath.rst | 71 ++++++++++++++++++++++++++++++++++++++ doc/en/usage.rst | 2 +- doc/en/writing_plugins.rst | 8 +++-- 9 files changed, 106 insertions(+), 17 deletions(-) create mode 100644 doc/en/pythonpath.rst diff --git a/_pytest/config.py b/_pytest/config.py index 4698ba790..d0ec62096 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -1079,7 +1079,6 @@ class Config(object): self.pluginmanager.load_setuptools_entrypoints('pytest11') self.pluginmanager.consider_env() self.known_args_namespace = ns = self._parser.parse_known_args(args, namespace=self.option.copy()) - confcutdir = self.known_args_namespace.confcutdir if self.known_args_namespace.confcutdir is None and self.inifile: confcutdir = py.path.local(self.inifile).dirname self.known_args_namespace.confcutdir = confcutdir diff --git a/doc/en/cache.rst b/doc/en/cache.rst index 688b6dd04..f3da3e6d6 100644 --- a/doc/en/cache.rst +++ b/doc/en/cache.rst @@ -1,3 +1,5 @@ +.. _cache: + Cache: working with cross-testrun state ======================================= diff --git a/doc/en/contents.rst b/doc/en/contents.rst index 9f4a9a1be..4f5bf789f 100644 --- a/doc/en/contents.rst +++ b/doc/en/contents.rst @@ -31,9 +31,10 @@ Full pytest documentation plugins writing_plugins - example/index goodpractices + pythonpath customize + example/index bash-completion backwards-compatibility diff --git a/doc/en/customize.rst b/doc/en/customize.rst index ce0a36c11..215e6ddd0 100644 --- a/doc/en/customize.rst +++ b/doc/en/customize.rst @@ -1,5 +1,5 @@ -Basic test configuration -=================================== +Configuration +============= Command line options and configuration file settings ----------------------------------------------------------------- @@ -15,17 +15,31 @@ which were registered by installed plugins. .. _rootdir: .. _inifiles: -initialization: determining rootdir and inifile +Initialization: determining rootdir and inifile ----------------------------------------------- .. versionadded:: 2.7 -pytest determines a "rootdir" for each test run which depends on +pytest determines a ``rootdir`` for each test run which depends on the command line arguments (specified test files, paths) and on -the existence of inifiles. The determined rootdir and ini-file are -printed as part of the pytest header. The rootdir is used for constructing -"nodeids" during collection and may also be used by plugins to store -project/testrun-specific information. +the existence of *ini-files*. The determined ``rootdir`` and *ini-file* are +printed as part of the pytest header during startup. + +Here's a summary what ``pytest`` uses ``rootdir`` for: + +* Construct *nodeids* during collection; each test is assigned + a unique *nodeid* which is rooted at the ``rootdir`` and takes in account full path, + class name, function name and parametrization (if any). + +* Is used by plugins as a stable location to store project/test run specific information; + for example, the internal :ref:`cache ` plugin creates a ``.cache`` subdirectory + in ``rootdir`` to store its cross-test run state. + +Important to emphasize that ``rootdir`` is **NOT** used to modify ``sys.path``/``PYTHONPATH`` or +influence how modules are imported. See :ref:`pythonpath` for more details. + +Finding the ``rootdir`` +~~~~~~~~~~~~~~~~~~~~~~~ Here is the algorithm which finds the rootdir from ``args``: diff --git a/doc/en/example/index.rst b/doc/en/example/index.rst index 363de5ab7..f63cb822a 100644 --- a/doc/en/example/index.rst +++ b/doc/en/example/index.rst @@ -1,8 +1,8 @@ .. _examples: -Usages and Examples -=========================================== +Examples and customization tricks +================================= Here is a (growing) list of examples. :ref:`Contact ` us if you need more examples or have questions. Also take a look at the diff --git a/doc/en/nose.rst b/doc/en/nose.rst index 5effd0d7b..10a10633a 100644 --- a/doc/en/nose.rst +++ b/doc/en/nose.rst @@ -26,7 +26,7 @@ Supported nose Idioms * setup and teardown at module/class/method level * SkipTest exceptions and markers * setup/teardown decorators -* ``yield``-based tests and their setup +* ``yield``-based tests and their setup (considered deprecated as of pytest 3.0) * ``__test__`` attribute on modules/classes/functions * general usage of nose utilities diff --git a/doc/en/pythonpath.rst b/doc/en/pythonpath.rst new file mode 100644 index 000000000..67de7f5d2 --- /dev/null +++ b/doc/en/pythonpath.rst @@ -0,0 +1,71 @@ +.. _pythonpath: + +pytest import mechanisms and ``sys.path``/``PYTHONPATH`` +======================================================== + +Here's a list of scenarios where pytest may need to change ``sys.path`` in order +to import test modules or ``conftest.py`` files. + +Test modules / ``conftest.py`` files inside packages +---------------------------------------------------- + +Consider this file and directory layout:: + + root/ + |- foo/ + |- __init__.py + |- conftest.py + |- bar/ + |- __init__.py + |- tests/ + |- __init__.py + |- test_foo.py + + +When executing:: + + pytest root/ + + + +pytest will find ``foo/bar/tests/test_foo.py`` and realize it is part of a package given that +there's an ``__init__.py`` file in the same folder. It will then search upwards until it can find the +last folder which still contains an ``__init__.py`` file in order to find the package *root* (in +this case ``foo/``). To load the module, it will insert ``root/`` to the front of +``sys.path`` (if not there already) in order to load +``test_foo.py`` as the *module* ``foo.bar.tests.test_foo``. + +The same logic applies to the ``conftest.py`` file: it will be imported as ``foo.conftest`` module. + +Preserving the full package name is important when tests live in a package to avoid problems +and allow test modules to have duplicated names. This is also discussed in details in +:ref:`test discovery`. + +Standalone test modules / ``conftest.py`` files +----------------------------------------------- + +Consider this file and directory layout:: + + root/ + |- foo/ + |- conftest.py + |- bar/ + |- tests/ + |- test_foo.py + + +When executing:: + + pytest root/ + +pytest will find ``foo/bar/tests/test_foo.py`` and realize it is NOT part of a package given that +there's no ``__init__.py`` file in the same folder. It will then add ``root/foo/bar/tests`` to +``sys.path`` in order to import ``test_foo.py`` as the *module* ``test_foo``. The same is done +with the ``conftest.py`` file by adding ``root/foo`` to ``sys.path`` to import it as ``conftest``. + +For this reason this layout cannot have test modules with the same name, as they all will be +imported in the global import namespace. + +This is also discussed in details in :ref:`test discovery`. + + diff --git a/doc/en/usage.rst b/doc/en/usage.rst index 763328f5a..775297882 100644 --- a/doc/en/usage.rst +++ b/doc/en/usage.rst @@ -17,7 +17,7 @@ You can invoke testing through the Python interpreter from the command line:: python -m pytest [...] This is almost equivalent to invoking the command line script ``pytest [...]`` -directly, except that python will also add the current directory to ``sys.path``. +directly, except that Python will also add the current directory to ``sys.path``. Possible exit codes -------------------------------------------------------------- diff --git a/doc/en/writing_plugins.rst b/doc/en/writing_plugins.rst index 861f2f48a..26e1a8a69 100644 --- a/doc/en/writing_plugins.rst +++ b/doc/en/writing_plugins.rst @@ -49,7 +49,7 @@ Plugin discovery order at tool startup Note that pytest does not find ``conftest.py`` files in deeper nested sub directories at tool startup. It is usually a good idea to keep - your conftest.py file in the top level test or project root directory. + your ``conftest.py`` file in the top level test or project root directory. * by recursively loading all plugins specified by the ``pytest_plugins`` variable in ``conftest.py`` files @@ -94,10 +94,12 @@ Here is how you might run it:: If you have ``conftest.py`` files which do not reside in a python package directory (i.e. one containing an ``__init__.py``) then "import conftest" can be ambiguous because there might be other - ``conftest.py`` files as well on your PYTHONPATH or ``sys.path``. + ``conftest.py`` files as well on your ``PYTHONPATH`` or ``sys.path``. It is thus good practice for projects to either put ``conftest.py`` under a package scope or to never import anything from a - conftest.py file. + ``conftest.py`` file. + + See also: :ref:`pythonpath`. Writing your own plugin From 61219da0e29a0e72907d3047fca401a751d5703c Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 22 Jul 2017 15:58:12 -0300 Subject: [PATCH 2/3] Update PR guide and add a "short" version --- CONTRIBUTING.rst | 69 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 71d70e8b7..b3bdde78b 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -158,19 +158,39 @@ As stated, the objective is to share maintenance and avoid "plugin-abandon". .. _`pull requests`: .. _pull-requests: -Preparing Pull Requests on GitHub ---------------------------------- +Preparing Pull Requests +----------------------- -.. note:: - What is a "pull request"? It informs project's core developers about the - changes you want to review and merge. Pull requests are stored on - `GitHub servers `_. - Once you send a pull request, we can discuss its potential modifications and - even add more commits to it later on. +Short version +~~~~~~~~~~~~~ -There's an excellent tutorial on how Pull Requests work in the -`GitHub Help Center `_, -but here is a simple overview: +#. Fork the repository; +#. Target ``master`` for bug-fix and doc changes; +#. Target ``features`` for new features or functionality changes. +#. Follow **PEP-8**. There's a ``tox`` command to help fixing it: ``tox -e fix-lint``. +#. Tests are run using ``tox``:: + + tox -e linting,py27,py36 + + The test environments above are usually enough to to cover most cases locally. + +#. Write a ``changelog`` entry: ``changelog/2574.bugfix``, use issue id number and one of + ``bugfix``, ``removal``, ``feature``, ``vendor``, ``doc`` or ``trivial`` for the issue type. +#. Add yourself to ``AUTHORS`` file if not there yet, in alphabetical order. + + +Long version +~~~~~~~~~~~~ + + +What is a "pull request"? It informs project's core developers about the +changes you want to review and merge. Pull requests are stored on +`GitHub servers `_. +Once you send a pull request, we can discuss its potential modifications and +even add more commits to it later on. There's an excellent tutorial on how Pull Requests work in the +`GitHub Help Center `_. + +Here is a simple overview, with pytest-specific bits: #. Fork the `pytest GitHub repository `__. It's @@ -212,19 +232,20 @@ but here is a simple overview: $ tox -e linting,py27,py36 This command will run tests via the "tox" tool against Python 2.7 and 3.6 - and also perform "lint" coding-style checks. If you have too much linting errors, - try running:: + and also perform "lint" coding-style checks. - $ tox -e fix-lint - - To fix pep8 related errors. - -#. You can now edit your local working copy. +#. You can now edit your local working copy. Please follow PEP-8. You can now make the changes you want and run the tests again as necessary. - To run tests on Python 2.7 and pass options to pytest (e.g. enter pdb on - failure) to pytest you can do:: + If you have too much linting errors, try running:: + + $ tox -e fix-lint + + To fix pep8 related errors. + + You can pass different options to ``tox``. For example, to run tests on Python 2.7 and pass options to pytest + (e.g. enter pdb on failure) to pytest you can do:: $ tox -e py27 -- --pdb @@ -237,9 +258,11 @@ but here is a simple overview: $ git commit -a -m "" $ git push -u - Make sure you add a message to ``CHANGELOG.rst`` and add yourself to - ``AUTHORS``. If you are unsure about either of these steps, submit your - pull request and we'll help you fix it up. +#. Create a new changelog entry in ``changelog``. The file should be named ``.``, + where *issueid* is the number of the issue related to the change and *type* is one of + ``bugfix``, ``removal``, ``feature``, ``vendor``, ``doc`` or ``trivial``. + +#. Add yourself to ``AUTHORS`` file if not there yet, in alphabetical order. #. Finally, submit a pull request through the GitHub website using this data:: From 0aa2480e6a0659b4f714fccf0d4784717903bfba Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 22 Jul 2017 22:11:51 -0300 Subject: [PATCH 3/3] Fix travis build after change from "precise" to "trusty" Travis recently has changed its dist from "precise" to "trusty", so some Python versions are no longer installed by default --- .travis.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0a71e7dc1..a90101e52 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,12 +11,9 @@ env: - TOXENV=coveralls # note: please use "tox --listenvs" to populate the build matrix below - TOXENV=linting - - TOXENV=py26 - TOXENV=py27 - - TOXENV=py33 - TOXENV=py34 - TOXENV=py35 - - TOXENV=pypy - TOXENV=py27-pexpect - TOXENV=py27-xdist - TOXENV=py27-trial @@ -30,6 +27,12 @@ env: matrix: include: + - env: TOXENV=py26 + python: '2.6' + - env: TOXENV=py33 + python: '3.3' + - env: TOXENV=pypy + python: 'pypy-5.4' - env: TOXENV=py36 python: '3.6' - env: TOXENV=py37