.. highlightlang:: python .. _`good practises`: 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 continous integration server Hudson_. .. _`virtualenv`: http://pypi.python.org/pypi/virtualenv .. _`buildout`: http://www.buildout.org/ .. _pip: http://pypi.python.org/pypi/pip .. _`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: * ``basedir`` = first upward directory not containing an ``__init__.py`` * perform ``sys.path.insert(0, basedir)``. * ``import path.to.test_module`` .. _standalone: .. _`genscript method`: Generating 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 and then e.g. run it like this to produce a Paste URL:: python runtests.py --pastebin=all and ask them to send you the resulting URL. .. _`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. .. include:: links.inc