« Back to Index

[Python Tox Explanation]

View original Gist on GitHub

Tags: #python #tox #testing

Python Tox Explanation.md

Tox is a tool that creates virtual environments, and installs the configured dependencies for those environments, for the purpose of testing a Python package (i.e. something that will be shared via PyPi, and so it only works with code that defines a setup.py).

The file that you use to configure tox can be one of the following…

Note: these are all ini file formats.

All configuration options for tox can be found here: tox.readthedocs.io/en/latest/config.html

Example tox.ini

Note: the name after testenv: is the name of the virtual environment that will be created (e.g. testenv:foo will create a “foo” virtual environment).

[tox]
envlist = 
    py37, lint
toxworkdir = 
    {env:TOX_WORK_DIR}

[testenv]
setenv =
    PYTHONDONTWRITEBYTECODE = 1
whitelist_externals =
    /bin/bash
deps = 
    -rrequirements-dev.txt
commands =
    py.test --cov={envsitepackagesdir}/bf_tornado -m "not integration"

[testenv:dev]
usedevelop=True
recreate = False
commands =
    # to run arbitrary commands: tox -e dev -- bash
    {posargs:py.test --cov=bf_tornado}

[testenv:lint]
deps = flake8==3.7.9
commands =
    flake8 bf_tornado

Configuring other packages

A tox.ini file can be used to configure different types of packages, which is confusing at first because the tox home page suggests that tox is used to test your own packages you plan on distributing to PyPi.

What is meant by that is the tox command itself is used to handle testing your packages, while the tox.ini configuration file is just one such file that can be used to contain configuration information.

This is why other packages, such as Flake8 allow you to configure it using the tox.ini file (or alternatively either setup.cfg or .flake8 files can be used).

The key to understanding why this works is as so: each of these files conforms to the ini file format. So you’re free to use whatever file ‘name’ you feel best suits your project, while the format of the file will stay consistent to what is expected of an .ini file.

Below is an example that shows various Python packages being configured within a tox.ini file.

In case it’s unclear, the configuration inside of the tox.ini file is used instead of having to pass those configuration values via the command line. So in the case of a tool such as flake8, instead of using flake8 --max-line-length=120 you could just call flake8 and the flag value is extracted from the configuration file.

[flake8]
max_line_length = 120
ignore = E261,E265,E402  # http://pep8.readthedocs.org/en/latest/intro.html#error-codes

[coverage:run]
branch = True

[coverage:report]
show_missing = True
exclude_lines =
    raise NotImplementedError
    return NotImplemented
    def __repr__
omit = bf_tornado/testing.py

[pytest]
addopts = 
    --strict -p no:cacheprovider --showlocals
markers =
    integration: mark a test as an integration test that makes http calls.