.. highlightlang:: python .. _`goodpractises`: Good Integration Practises ================================================= Work with virtual environments ----------------------------------------------------------- We recommend to work with virtualenv_ environments and use easy_install_ (or pip_) for installing your application dependencies as well as the ``pytest`` package itself. This way you get a much more reproducible environment. A good tool to help you automate test runs against multiple dependency configurations or Python interpreters is `tox`_, independently created by the main py.test author. The latter is also useful for integration with the continuous integration server Hudson_. .. _`virtualenv`: http://pypi.python.org/pypi/virtualenv .. _`buildout`: http://www.buildout.org/ .. _pip: http://pypi.python.org/pypi/pip Use tox and Continuous Integration servers ------------------------------------------------- If you are (often) releasing code to the public you may want to look into `tox`_, the virtualenv test automation tool and its `pytest support `_. The basic idea is to generate a JUnitXML file through the ``--junitxml=PATH`` option and have a continuous integration server like Hudson_ pick it up. .. _standalone: .. _`genscript method`: 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:: py.test --genscript=runtests.py 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 .. _`Distribute for installation`: http://pypi.python.org/pypi/distribute#installation-instructions .. _`distribute installation`: http://pypi.python.org/pypi/distribute Integrating with distutils / ``python setup.py test`` -------------------------------------------------------- You can easily integrate test runs into your distutils or setuptools based project. Use the `genscript method`_ to generate a standalone py.test script:: py.test --genscript=runtests.py and make this script part of your distribution and then add this to your ``setup.py`` file:: from distutils.core import setup, Command # you can also import from setuptools class PyTest(Command): user_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): import sys,subprocess errno = subprocess.call([sys.executable, 'runtest.py']) raise SystemExit(errno) setup( #..., cmdclass = {'test': PyTest}, #..., ) If you now type:: python setup.py test this will execute your tests using ``runtest.py``. As this is a standalone version of ``py.test`` no prior installation whatsoever is required for calling the test command. You can also pass additional arguments to the subprocess-calls like your test directory or other options. .. _`test discovery`: .. _`Python test discovery`: Conventions for Python test discovery ------------------------------------------------- ``py.test`` implements the following standard test discovery: * collection starts from initial command line arguments which may be directories, filenames or test ids. * recurse into directories, unless they match :confval:`norecursedirs` * ``test_*.py`` or ``*_test.py`` files, imported by their `package name`_. * ``Test`` prefixed test classes (without an ``__init__`` method) * ``test_`` prefixed test functions or methods are test items For changing and customization example, see :doc:`example/pythoncollection`. py.test additionally discovers tests using the standard :ref:`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 ... You can always 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:: Test modules are imported under their fully qualified name as follows: * find ``basedir`` -- this is the first "upward" directory not containing an ``__init__.py`` * perform ``sys.path.insert(0, basedir)`` to make the fully qualified test module path importable. * ``import path.to.test_module`` where the path is determined by converting path separators into "." files. This means you must follow the convention of having directory and file names map to the import names. .. include:: links.inc