CNK's Blog

Running TOX locally

TL;DR Install tox and virtualenv-pyenv python packages. In the shell, export VIRTUALENV_DISCOVERY=pyenv. And in the tox.ini add the following to the setenv section: VIRTUALENV_DISCOVERY=pyenv


I needed to to do some long deferred maintenance on the wagtail-hallo package we still use. I have neglected it for so long I feel like I need to test it on several different versions of Wagtail. The package’s CI setup already runs some basic python tests for several combinations Python, Django, Wagtail, and 2 databases. So I thought I would start by running those automated tests locally - and then move onto browser testing.

So how do I run tox locally? Per usual, there is the official documentation which is thourough and overwhelming. But this one pager from the OpenAstronomy Python Packaging Guide was much more what I needed to get started. That explained the structure of my existing tox.ini file and showed me how to run individual test environments - or all of them. I didn’t want to have to set up postgres so the first thing I did was to remove postgres from the database options - leaving only the sqlite environments. Then I did pip install tox into the virtual environment I use for developing Wagtail - currently Python 3.12.5, Django 5.0, and wagtail plus its dependencies from sha a5761bc2a961a8c91e5482d2e301191f617fe3d4.

The first time I ran tox, some of the sets ran but most of them said they couldn’t find an appropriate python - even for pythons I know I have installed in my pyenv setup. ChatGPT told me I needed to install tox-pyenv but when I looked at its GitHub README, that project is archived and it tells me I need a different package: virtualenv-pyenv.

After a little bit of searching, I found virtualenv-pyenv and was able to install it: pip install virtualenv-pyenv. I added the required environment variable to my bash profile: VIRTUALENV_DISCOVERY=pyenv and then edited the tox.ini file to add a new environment variable:

    setenv =
        postgres: DATABASE_URL={env:DATABASE_URL:postgres:///wagtail_hallo}
        VIRTUALENV_DISCOVERY=pyenv

So at this point, I have the following tox-related packages in my virtual environment:

   tox==4.23.2
   virtualenv==20.28.0
   virtualenv-pyenv==0.5.0

And now when I ran tox again, most of my tests ran:

    python3.8-django3.2-wagtail3.0-sqlite: SKIP (0.01 seconds)
    python3.9-django3.2-wagtail3.0-sqlite: SKIP (0.00 seconds)
    python3.10-django3.2-wagtail3.0-sqlite: OK (15.19=setup[10.32]+cmd[4.87] seconds)
    python3.9-django4.1-wagtail4.2-sqlite: SKIP (0.00 seconds)
    python3.10-django4.1-wagtail4.2-sqlite: OK (15.41=setup[8.17]+cmd[7.25] seconds)
    python3.11-django4.1-wagtail4.2-sqlite: OK (15.46=setup[8.02]+cmd[7.44] seconds)
    python3.10-django4.2-wagtail5.2-sqlite: OK (14.53=setup[7.81]+cmd[6.72] seconds)
    python3.10-django4.2-wagtail6.1-sqlite: OK (14.67=setup[7.50]+cmd[7.17] seconds)
    python3.10-django5.0-wagtail5.2-sqlite: OK (14.43=setup[7.42]+cmd[7.01] seconds)
    python3.10-django5.0-wagtail6.1-sqlite: OK (15.05=setup[7.38]+cmd[7.67] seconds)
    python3.11-django4.2-wagtail5.2-sqlite: OK (14.03=setup[7.36]+cmd[6.66] seconds)
    python3.11-django4.2-wagtail6.1-sqlite: OK (14.32=setup[7.08]+cmd[7.24] seconds)
    python3.11-django5.0-wagtail5.2-sqlite: OK (14.19=setup[7.07]+cmd[7.12] seconds)
    python3.11-django5.0-wagtail6.1-sqlite: OK (14.74=setup[7.11]+cmd[7.63] seconds)
    python3.12-django4.2-wagtail5.2-sqlite: OK (6.48=setup[0.01]+cmd[6.47] seconds)
    python3.12-django4.2-wagtail6.1-sqlite: OK (6.81=setup[0.01]+cmd[6.81] seconds)
    python3.12-django5.0-wagtail5.2-sqlite: OK (6.67=setup[0.01]+cmd[6.66] seconds)
    python3.12-django5.0-wagtail6.1-sqlite: OK (7.46=setup[0.01]+cmd[7.45] seconds)
    congratulations :) (189.50 seconds)

Locally I don’t care about python 3.8 and 3.9, so I am just going to ignore them. The messages in the console appear to indicate that pyenv doesn’t have packages for those older pythons:

    skipped because could not find python interpreter with spec(s): python3.9
    only CPython is currently supported