What is Tox and Why is it Useful?

According to the official Tox documentation

tox is a generic virtual environment management and test command line tool you can use for:

  • checking your package builds and installs correctly under different environments (such as different Python implementations, versions or installation dependencies),

  • running your tests in each of the environments with the test tool of choice,

  • acting as a frontend to continuous integration servers, greatly reducing boilerplate and merging CI and shell-based testing.

Tox is an essential tool in Python development, primarily used for testing your code in multiple environments.

It shines in scenarios where your application needs to run across different Python versions or configurations.

Configuration in tox is specified using the tox.ini file.

For example, a basic tox.ini file may look like this:

[tox]
requires =  
    tox>=4  
env_list =   
    py{310,311,312}  
    lint  
    type  
    coverage  
  

Introduction to Poetry

Poetry is a modern tool in Python for dependency management and packaging, designed to address the complexities and shortcomings of traditional tools like pip, pipenv, venv, and Conda.

Using Tox

To use tox, all you need are a couple of things.

  • Install tox using pip or pipx, read more here.

  • Define tox configuration in a tox.ini file.

Note — You can also generate a tox.ini file automatically by running tox quickstart and then answering a few interactive questions.

Running Tox

Now let’s run our tox environment using the tox command

Pass Pytest CLI Arguments to Tox

For example, only run a specific test, increase verbosity or use a custom logging?

By passing the value commands = pytest {posargs:tests} in our tox.ini file, we tell tox to allow us to pass custom arguments to this Pytest command.

tox — -v -s

Running a Single Test

tox — tests/test_calculator.py::test_division_by_zero -v

Formatting and Linting with Tox

Or check PEP8 compliance and formatting? (using Black or Ruff).

It’s easy to add these steps in tox.

Next, we install our dependencies using poetry install

Using Tox with Poetry

Let’s update our tox.ini file and add a coverage section.

[tox]  
requires =  
    tox>=4  
env_list =   
    py{310,311,312}  
    lint  
    type  
    coverage  
  
[testenv]  
description = run the tests with pytest  
skip_install = true  
allowlist_externals = poetry  
commands_pre =  
    poetry install  
commands =   
    poetry run pytest {posargs:tests}  
  
[testenv:type]  
description = run type checks  
skip_install = true  
allowlist_externals = poetry  
commands_pre =  
    poetry install  
commands =  
    poetry run mypy {posargs:src tests}  
  
[testenv:lint]  
description = run linter  
skip_install = true  
allowlist_externals = poetry  
commands_pre =  
    poetry install  
commands = poetry run ruff {posargs:src tests}  
  
[testenv:coverage]  
description = run coverage report  
skip_install = true  
allowlist_externals = poetry  
commands_pre =  
    poetry install  
commands = poetry run pytest --cov=src tests/

Build and Publish Package

Among the last steps, you can build your Python package using the poetry build command.