[Pytest-commit] commit/pytest: hpk42: close issue240 - rework "good practises" document and discuss
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Tue Dec 10 14:54:42 CET 2013
1 new commit in pytest:
https://bitbucket.org/hpk42/pytest/commits/23152b79f1dc/
Changeset: 23152b79f1dc
User: hpk42
Date: 2013-12-10 14:54:13
Summary: close issue240 - rework "good practises" document and discuss
discuss the two common test directory layouts in more detail, including
an explicit note on how it interacts with PEP420-namespace packages.
Affected #: 2 files
diff -r 4c16e1c06b5d0bcad11840fba22bc7604c1f1fbd -r 23152b79f1dc6ad64a2e6a73a327b770352ca6f7 CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -26,6 +26,10 @@
with repeated same values (sometimes useful to to test if calling
a second time works as with the first time).
+- close issue240 - document precisely how pytest module importing
+ works, discuss the two common test directory layouts, and how it
+ interacts with PEP420-namespace packages.
+
- fix issue246 fix finalizer order to be LIFO on independent fixtures
depending on a parametrized higher-than-function scoped fixture.
(was quite some effort so please bear with the complexity of this sentence :)
diff -r 4c16e1c06b5d0bcad11840fba22bc7604c1f1fbd -r 23152b79f1dc6ad64a2e6a73a327b770352ca6f7 doc/en/goodpractises.txt
--- a/doc/en/goodpractises.txt
+++ b/doc/en/goodpractises.txt
@@ -8,24 +8,151 @@
Work with virtual environments
-----------------------------------------------------------
-We recommend to use virtualenv_ environments and use easy_install_
-(or pip_) for installing your application dependencies as well as
-the ``pytest`` package itself. This way you will get a much more reproducible
-environment. A good tool to help you automate test runs against multiple
-dependency configurations or Python interpreters is `tox`_.
+We recommend to use virtualenv_ environments and use pip_
+(or easy_install_) for installing your application and any dependencies
+as well as the ``pytest`` package itself. This way you will get an isolated
+and reproducible environment. Given you have installed virtualenv_
+and execute it from the command line, here is an example session for unix
+or windows::
+
+ virtualenv . # create a virtualenv directory in the current directory
+
+ source bin/activate # on unix
+
+ scripts/activate # on Windows
+
+We can now install pytest::
+
+ pip install pytest
+
+Due to the ``activate`` step above the ``pip`` will come from
+the virtualenv directory and install any package into the isolated
+virtual environment.
+
+Choosing a test layout / import rules
+------------------------------------------
+
+py.test supports two common test layouts:
+
+* putting tests into an extra directory outside your actual application
+ code, useful if you have many functional tests or for other reasons
+ want to keep tests separate from actual application code (often a good
+ idea)::
+
+ setup.py # your distutils/setuptools Python package metadata
+ mypkg/
+ __init__.py
+ appmodule.py
+ tests/
+ test_app.py
+ ...
+
+
+* inlining test directories into your application package, useful if you
+ have direct relation between (unit-)test and application modules and
+ want to distribute your tests along with your application::
+
+ setup.py # your distutils/setuptools Python package metadata
+ mypkg/
+ __init__.py
+ appmodule.py
+ ...
+ test/
+ test_app.py
+ ...
+
+Important notes relating to both schemes:
+
+- **make sure that "mypkg" is importable**, for example by typing once::
+
+ pip install -e . # install package using setup.py in editable mode
+
+- **avoid "__init__.py" files in your test directories**.
+ This way your tests can run easily against an installed version
+ of ``mypkg``, independently from if the installed version contains
+ the tests or not.
+
+- With inlined tests you might put ``__init__.py`` into test
+ directories and make them installable as part of your application.
+ Using the ``py.test --pyargs mypkg`` invocation pytest will
+ discover where mypkg is installed and collect tests from there.
+ With the "external" test you can still distribute tests but they
+ will not be installed or become importable.
+
+Typically you can run tests by pointing to test directories or modules::
+
+ py.test tests/test_app.py # for external test dirs
+ py.test mypkg/test/test_app.py # for inlined test dirs
+ py.test mypkg # run tests in all below test directories
+ py.test # run all tests below current dir
+ ...
+
+Because of the above ``editable install`` mode you can change your
+source code (both tests and the app) and rerun tests at will.
+Once you are done with your work, you can `use tox`_ to make sure
+that the package is really correct and tests pass in all
+required configurations.
+
+.. note::
+
+ You can use Python3 namespace packages (PEP420) for your application
+ but pytest will still perform `package name`_ discovery based on the
+ presence of ``__init__.py`` files. If you use one of the above
+ two recommended file system layouts but leave away the ``__init__.py``
+ files it should just work on Python3.3 and above. When using
+ "inlined tests", however, you will need to use absolute imports for
+ getting at your application code because the test modules will be
+ imported directly, without any application context. The latter allows
+ your tests to run against an installed version of your package.
+
+.. _`package name`:
+
+.. note::
+
+ If py.test finds a "a/b/test_module.py" test file while
+ recursing into the filesystem it determines the import name
+ as follows:
+
+ * determine ``basedir``: this is the first "upward" (towards the root)
+ directory not containing an ``__init__.py``. If e.g. both ``a``
+ and ``b`` contain an ``__init__.py`` file then the parent directory
+ of ``a`` will become the ``basedir``.
+
+ * perform ``sys.path.insert(0, basedir)`` to make the test module
+ importable under the fully qualified import name.
+
+ * ``import a.b.test_module`` where the path is determined
+ by converting path separators ``/`` into "." characters. This means
+ you must follow the convention of having directory and file
+ names map directly to the import names.
+
+ The reason for this somewhat evolved importing technique is
+ that in larger projects multiple test modules might import
+ from each other and thus deriving a canonical import name helps
+ to avoid surprises such as a test modules getting imported twice.
+
.. _`virtualenv`: http://pypi.python.org/pypi/virtualenv
.. _`buildout`: http://www.buildout.org/
.. _pip: http://pypi.python.org/pypi/pip
+.. _`use tox`:
+
Use tox and Continuous Integration servers
-------------------------------------------------
-If you frequently release code to the public you
-may want to look into `tox`_, the virtualenv test automation
-tool and its `pytest support <http://testrun.org/tox/latest/example/pytest.html>`_.
-The basic idea is to generate a JUnitXML file through the ``--junitxml=PATH`` option and have a continuous integration server like Jenkins_ pick it up
-and generate reports.
+If you frequently release code and want to make sure that your actual
+package passes all tests you may want to look into `tox`_, the
+virtualenv test automation tool and its `pytest support
+<http://testrun.org/tox/latest/example/pytest.html>`_.
+Tox helps you to setup virtualenv environments with pre-defined
+dependencies and then executing a pre-configured test command with
+options. It will run tests against the installed package and not
+against your source code checkout, helping to detect packaging
+glitches.
+
+If you want to use Jenkins_ you can use the ``--junitxml=PATH`` option
+to create a JUnitXML file that Jenkins_ can pick up and generate reports.
.. _standalone:
.. _`genscript method`:
@@ -33,21 +160,19 @@
Create a py.test standalone script
-------------------------------------------
-If you are a maintainer or application developer and want others
-to easily run tests you can generate a completely standalone "py.test"
-script::
+If you are a maintainer or application developer and want people
+who don't deal with python much to easily run tests you may generate
+a standalone "py.test" script::
py.test --genscript=runtests.py
-generates a ``runtests.py`` script which is a fully functional basic
+This generates a ``runtests.py`` script which is a fully functional basic
``py.test`` script, running unchanged under Python2 and Python3.
You can tell people to download the script and then e.g. run it like this::
python runtests.py
-
-
Integrating with distutils / ``python setup.py test``
--------------------------------------------------------
@@ -93,8 +218,9 @@
Integration with setuptools test commands
----------------------------------------------------
-Setuptools supports writing our own Test command for invoking
-pytest::
+Setuptools supports writing our own Test command for invoking pytest.
+Most often it is better to use tox_ instead, but here is how you can
+get started with setuptools integration::
from setuptools.command.test import test as TestCommand
import sys
@@ -143,69 +269,4 @@
Within Python modules, py.test also discovers tests using the standard
:ref:`unittest.TestCase <unittest.TestCase>` subclassing technique.
-Choosing a test layout / import rules
-------------------------------------------
-
-py.test supports common test layouts:
-
-* inlining test directories into your application package, useful if you want to
- keep (unit) tests and actually tested code close together::
-
- mypkg/
- __init__.py
- appmodule.py
- ...
- test/
- test_app.py
- ...
-
-* putting tests into an extra directory outside your actual application
- code, useful if you have many functional tests or want to keep
- tests separate from actual application code::
-
- mypkg/
- __init__.py
- appmodule.py
- tests/
- test_app.py
- ...
-
-In both cases you usually need to make sure that ``mypkg`` is importable,
-for example by using the setuptools ``python setup.py develop`` method.
-
-You can run your tests by pointing to it::
-
- py.test tests/test_app.py # for external test dirs
- py.test mypkg/test/test_app.py # for inlined test dirs
- py.test mypkg # run tests in all below test directories
- py.test # run all tests below current dir
- ...
-
-.. _`package name`:
-
-.. note::
-
- If py.test finds a "a/b/test_module.py" test file while
- recursing into the filesystem it determines the import name
- as follows:
-
- * find ``basedir`` -- this is the first "upward" (towards the root)
- directory not containing an ``__init__.py``. If both the ``a``
- and ``b`` directories contain an ``__init__.py`` the basedir will
- be the parent dir of ``a``.
-
- * perform ``sys.path.insert(0, basedir)`` to make the test module
- importable under the fully qualified import name.
-
- * ``import a.b.test_module`` where the path is determined
- by converting path separators ``/`` into "." characters. This means
- you must follow the convention of having directory and file
- names map directly to the import names.
-
- The reason for this somewhat evolved importing technique is
- that in larger projects multiple test modules might import
- from each other and thus deriving a canonical import name helps
- to avoid surprises such as a test modules getting imported twice.
-
-
.. include:: links.inc
Repository URL: https://bitbucket.org/hpk42/pytest/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the pytest-commit
mailing list