Skip to content

Commit

Permalink
Attempt to clarify the confusion regarding __init__ files and unique …
Browse files Browse the repository at this point in the history
…test names

Fix #529
  • Loading branch information
nicoddemus committed Mar 9, 2017
1 parent 906b40f commit 841f731
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 47 deletions.
85 changes: 38 additions & 47 deletions doc/en/goodpractices.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,68 +30,58 @@ Within Python modules, ``pytest`` also discovers tests using the standard


Choosing a test layout / import rules
------------------------------------------
-------------------------------------

``pytest`` 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)::
Tests outside application code
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

setup.py # your setuptools Python package metadata
Putting tests into an extra directory outside your actual application code
might be 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
mypkg/
__init__.py
appmodule.py
app.py
view.py
tests/
test_app.py
test_view.py
...

This way your tests can run easily against an installed version
of ``mypkg``.

Note that using this scheme your test files must have **unique names**, because
``pytest`` will import them as *top-level* modules since there are no packages
to derive a full package name from.

Tests as part of application code
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

* 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::
Inlining test directories into your application package
is useful if you have direct relation between tests and application modules and
want to distribute them along with your application::

setup.py # your setuptools Python package metadata
setup.py
mypkg/
__init__.py
appmodule.py
...
app.py
view.py
test/
__init__.py
test_app.py
test_view.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
In this scheme, it is easy to your tests using the ``--pyargs`` option::

- **avoid "__init__.py" files in your test directories**.
This way your tests can run easily against an installed version
of ``mypkg``, independently from the installed package if it contains
the tests or not.
pytest --pyargs mypkg

- With inlined tests you might put ``__init__.py`` into test
directories and make them installable as part of your application.
Using the ``pytest --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.
``pytest`` will discover where ``mypkg`` is installed and collect tests from there.

Typically you can run tests by pointing to test directories or modules::

pytest tests/test_app.py # for external test dirs
pytest mypkg/test/test_app.py # for inlined test dirs
pytest mypkg # run tests in all below test directories
pytest # 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::

Expand Down Expand Up @@ -144,7 +134,13 @@ for installing your application and any dependencies
as well as the ``pytest`` package itself. This ensures your code and
dependencies are isolated from the system Python installation.

If you frequently release code and want to make sure that your actual
You can then install your package in "editable" mode::

pip install -e .

which lets you change your source code (both tests and application) and rerun tests at will.

Once you are done with your work 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
<https://tox.readthedocs.io/en/latest/example/pytest.html>`_.
Expand All @@ -154,11 +150,6 @@ options. It will run tests against the installed package and not
against your source code checkout, helping to detect packaging
glitches.

Continuous integration services such as Jenkins_ can make use of the
``--junitxml=PATH`` option to create a JUnitXML file and generate reports (e.g.
by publishing the results in a nice format with the `Jenkins xUnit Plugin
<https://wiki.jenkins-ci.org/display/JENKINS/xUnit+Plugin>`_).


Integrating with setuptools / ``python setup.py test`` / ``pytest-runner``
--------------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ commands=
pytest -ra {posargs:testing/test_unittest.py}

[testenv:docs]
skipsdist=True
usedevelop=True
basepython=python
changedir=doc/en
deps=
Expand Down

0 comments on commit 841f731

Please sign in to comment.