# tox plugins

New in version 2.0.

A growing number of hooks make tox modifiable in different phases of execution by writing plugins.

tox - like pytest and devpi - uses pluggy to provide an extension mechanism for pip-installable internal or devpi/PyPI-published plugins.

## Using plugins

To start using a plugin you need to install it in the same environment where the tox host is installed.

e.g.:

    $ pip install tox-travis

You can search for available plugins on PyPI by typing `pip search tox` and filter for packages that are prefixed `tox-` or contain the word “plugin” in the description. You will get some output similar to this:

    tox-pipenv (1.4.1)                   - A pipenv plugin for tox
    tox-pyenv (1.1.0)                    - tox plugin that makes tox use ``pyenv which`` to find
                                           python executables
    tox-globinterpreter (0.3)            - tox plugin to allow specification of interpreter
                                           locationspaths to use
    tox-venv (0.2.0)                     - Use python3 venvs for python3 tox testenvs
    tox-cmake (0.1.1)                    - Build CMake projects using tox
    tox-tags (0.2.0)                     - Allows running subsets of environments based on tags
    tox-travis (0.10)                    - Seamless integration of tox into Travis CI
    tox-py-backwards (0.1)               - tox plugin for py-backwards
    tox-pytest-summary (0.1.2)           - tox + Py.test summary
    tox-envreport (0.2.0)                - A tox-plugin to document the setup of used virtual
                                           environments.
    tox-no-internet (0.1.0)              - Workarounds for using tox with no internet connection
    tox-virtualenv-no-download (1.0.2)   - Disable virtualenv's download-by-default in tox
    tox-run-command (0.4)                - tox plugin to run arbitrary commands in a virtualenv
    tox-pip-extensions (1.2.1)           - Augment tox with different installation methods via
                                           progressive enhancement.
    tox-run-before (0.1)                 - tox plugin to run shell commands before the test
                                           environments are created.
    tox-docker (1.0.0)                   - Launch a docker instance around test runs
    tox-bitbucket-status (1.0)           - Update bitbucket status for each env
    tox-pipenv-install (1.0.3)           - Install packages from Pipfile

There might also be some plugins not (yet) available from PyPI that could be installed directly from source hosters like Github or Bitbucket (or from a local clone). See the associated pip documentation.

To see what is installed you can call `tox --version` to get the version of the host and names and locations of all installed plugins:

    3.0.0 imported from /home/ob/.virtualenvs/tmp/lib/python3.6/site-packages/tox/__init__.py
    registered plugins:
        tox-travis-0.10 at /home/ob/.virtualenvs/tmp/lib/python3.6/site-packages/tox_travis/hooks.py

## Creating a plugin

Start from a template

You can create a new tox plugin with all the bells and whistles via a Cookiecutter template (see cookiecutter-tox-plugin - this will create a complete PyPI-releasable, documented project with license, documentation and CI.

    $ pip install -U cookiecutter
    $ cookiecutter gh:tox-dev/cookiecutter-tox-plugin

## Tutorial: a minimal tox plugin

Note

This is the minimal implementation to demonstrate what is absolutely necessary to have a working plugin for internal use. To move from something like this to a publishable plugin you could apply `cookiecutter -f cookiecutter-tox-plugin` and adapt the code to the package based structure used in the cookiecutter.

Let us consider you want to extend tox behaviour by displaying fireworks at the end of a successful tox run (we won’t go into the details of how to display fireworks though).

To create a working plugin you need at least a python project with a tox entry point and a python module implementing one or more of the pluggy-based hooks tox specifies (using the `@tox.hookimpl` decorator as marker).

minimal structure:

    $ mkdir tox-fireworks
    $ cd tox-fireworks
    $ touch tox_fireworks.py
    $ touch setup.py

contents of `tox_fireworks.py`:

    import pluggy

    hookimpl = pluggy.HookimplMarker("tox")

    @hookimpl
    def tox_addoption(parser):
        """Add command line option to display fireworks on request."""

    @hookimpl
    def tox_configure(config):
        """Post process config after parsing."""

    @hookimpl
    def tox_runenvreport(config):
        """Display fireworks if all was fine and requested."""

Note

See Hook specifications and related API for details

contents of `setup.py`:

    from setuptools import setup

    setup(
        name="tox-fireworks",
        py_modules=["tox_fireworks"],
        entry_points={"tox": ["fireworks = tox_fireworks"]},
        classifiers=["Framework:: tox"],
    )

Using the tox- prefix in `tox-fireworks` is an established convention to be able to see from the project name that this is a plugin for tox. It also makes it easier to find with e.g. `pip search 'tox-'` once it is released on PyPI.

To make your new plugin discoverable by tox, you need to install it. During development you should install it with `-e` or `--editable`, so that changes to the code are immediately active:

    $ pip install -e </path/to/tox-fireworks>

## Publish your plugin to PyPI

If you think the rest of the world could profit using your plugin, you can publish it to PyPI.

You need to add some more meta data to `setup.py` (see cookiecutter-tox-plugin for a complete example or consult the setup.py docs).

Note

Make sure your plugin project name is prefixed by `tox-` to be easy to find via e.g. `pip search tox-`

You can and publish it like:

    $ cd </path/to/tox-fireworks>
    $ python setup.py sdist bdist_wheel upload

Note

You could also use twine for secure uploads.

For more information about packaging and deploying Python projects see the Python Packaging Guide.

## Hook specifications and related API

Hook specifications for tox - see https://pluggy.readthedocs.io/

tox.hookspecs.tox_addoption(parser)

  add command line options to the argparse-style parser object.

tox.hookspecs.tox_cleanup(session)

  Called just before the session is destroyed, allowing any final cleanup operation

tox.hookspecs.tox_configure(config)

  Called after command line options are parsed and ini-file has been read.

  Please be aware that the config object layout may change between major tox versions.

tox.hookspecs.tox_get_python_executable(envconfig)

  Return a python executable for the given python base name.

  The first plugin/hook which returns an executable path will determine it.

  `envconfig` is the testenv configuration which contains per-testenv configuration, notably the `.envname` and `.basepython` setting.

tox.hookspecs.tox_package(session, venv)

  Return the package to be installed for the given venv.

  Called once for every environment.

tox.hookspecs.tox_runenvreport(venv, action)

  Get the installed packages and versions in this venv.

  This could be used for alternative (ie non-pip) package managers, this plugin should return a `list` of type `str`

tox.hookspecs.tox_runtest(venv, redirect)

  Run the tests for this venv.

  Note

  This hook uses `firstresult=True` (see pluggy first result only) – hooks implementing this will be run until one returns non-`None`.

tox.hookspecs.tox_runtest_post(venv)

  Perform arbitrary action after running tests for this venv.

  This could be used to have per-venv test reporting of pass/fail status.

tox.hookspecs.tox_runtest_pre(venv)

  Perform arbitrary action before running tests for this venv.

  This could be used to indicate that tests for a given venv have started, for instance.

tox.hookspecs.tox_testenv_create(venv, action)

  Perform creation action for this venv.

  Some example usage:

  - To add behavior but still use tox’s implementation to set up a virtualenv, implement this hook but do not return a value (or explicitly return `None`).

  - To override tox’s virtualenv creation, implement this hook and return a non-`None` value.

  Note

  This api is experimental due to the unstable api of `tox.venv.VirtualEnv`.

  Note

  This hook uses `firstresult=True` (see pluggy first result only) – hooks implementing this will be run until one returns non-`None`.

tox.hookspecs.tox_testenv_install_deps(venv, action)

  Perform install dependencies action for this venv.

  Some example usage:

  - To add behavior but still use tox’s implementation to install dependencies, implement this hook but do not return a value (or explicitly return `None`). One use-case may be to install (or ensure) non-python dependencies such as debian packages.

  - To override tox’s installation of dependencies, implement this hook and return a non-`None` value. One use-case may be to install via a different installation tool such as pip-accel or pip-faster.

  Note

  This api is experimental due to the unstable api of `tox.venv.VirtualEnv`.

  Note

  This hook uses `firstresult=True` (see pluggy first result only) – hooks implementing this will be run until one returns non-`None`.

class tox.config.Parser

  Command line and ini-parser control object.

  add_argument(*args, **kwargs)

    add argument to command line parser. This takes the same arguments that `argparse.ArgumentParser.add_argument`.

  add_testenv_attribute(name, type, help, default=None, postprocess=None)

    add an ini-file variable for “testenv” section.

    Types are specified as strings like “bool”, “line-list”, “string”, “argv”, “path”, “argvlist”.

    The `postprocess` function will be called for each testenv like `postprocess(testenv_config=testenv_config, value=value)` where `value` is the value as read from the ini (or the default value) and `testenv_config` is a `tox.config.TestenvConfig` instance which will receive all ini-variables as object attributes.

    Any postprocess function must return a value which will then be set as the final value in the testenv section.

  add_testenv_attribute_obj(obj)

    add an ini-file variable as an object.

    This works as the `add_testenv_attribute` function but expects “name”, “type”, “help”, and “postprocess” attributes on the object.

class tox.config.Config

  Global Tox config object.

  args

    option namespace containing all parsed command line options

  envconfigs

    Mapping envname -> envconfig

class tox.config.TestenvConfig

  Testenv Configuration object.

  In addition to some core attributes/properties this config object holds all per-testenv ini attributes as attributes, see “tox –help-ini” for an overview.

  config

    global tox config object

  envname

    test environment name

  property envpython

    Path to python executable.

  factors

    set of factors

  get_envbindir()

    Path to directory where scripts/binaries reside.

  get_envpython()

    path to python/jython executable.

  get_envsitepackagesdir()

    Return sitepackagesdir of the virtualenv environment.

    NOTE: Only available during execution, not during parsing.

  property python_info

    Return sitepackagesdir of the virtualenv environment.

class tox.venv.VirtualEnv
  getcommandpath(name, venv=True, cwd=None)

    Return absolute path (str or localpath) for specified command name.

    - If it’s a local path we will rewrite it as as a relative path.

    - If venv is True we will check if the command is coming from the venv or is allowed to come from external.

  property name

    test environment name.

  property path

    Path to environment base dir.

  update(action)

    return status string for updating actual venv to match configuration. if status string is empty, all is ok.

class tox.session.Session

  The session object that ties together configuration, reporting, venv creation, testing.