Lab Guide: Orchestrating Tests with tox-ansible
A guide to automating your testing workflow using the tox-ansible plugin.
Learning objectives
After completing this module, you will be able to:
-
Configure
tox-ansibleto auto-discover test environments -
Run linting, unit, and integration tests through a unified
toxinterface -
Target specific Ansible versions and test types using tox factors
Lab briefing
What is tox?
tox is a generic virtual environment management and test command line tool. It is the standard for testing Python-based projects.
What is tox-ansible?
tox-ansible is a plugin (installed by default in ansible-dev-tools) that makes tox "Ansible-aware." Instead of writing dozens of lines of configuration to tell tox how to run ansible-lint or molecule, the plugin scans your collection and automatically creates test environments for:
-
Linting: (ansible-lint)
-
Unit Tests: (pytest)
-
Sanity Tests: (ansible-test sanity)
-
Integration Tests: (molecule)
This "Convention over Configuration" approach allows you to run complex test matrices with a 5-line configuration file.
Lab guide: Hands-on tasks
Task 1: Verify the installation
Before we configure anything, let’s verify that tox and the plugin are installed and ready.
-
Open the VS Code Terminal.
-
Navigate to your collection root:
cd /projects/ansible-dev-tools-workspace/mynamespace.mycollection/ -
Check the tox version and plugins:
tox --versionOutput analysis: You should see output similar to:
$ tox --version ROOT: No loadable tox.ini or setup.cfg or pyproject.toml or tox.toml found, assuming empty tox.ini at /projects/ansible-dev-tools-workspace/mynamespace.mycollection 4.53.0 from /projects/ansible-dev-tools-workspace/mynamespace.mycollection/.venv/lib64/python3.12/site-packages/tox/__init__.py registered plugins: tox-ansible-26.3.0 at /projects/ansible-dev-tools-workspace/mynamespace.mycollection/.venv/lib64/python3.12/site-packages/tox_ansible/plugin.pyThe
ROOT: No loadable tox.inimessage is expected — tox-ansible uses its owntox-ansible.inifile instead oftox.ini. Look fortox-ansiblein the registered plugins list. This confirms the plugin is active.
Task 2: Configure tox-ansible
When ansible-creator scaffolded your collection, it created a tox-ansible.ini file. This is the configuration file for the tox-ansible plugin — it is separate from tox.ini on purpose, so it does not interfere with standard tox workflows.
The plugin uses tox-ansible.ini to control which Python versions and Ansible versions to include or skip in the test matrix. Without it, tox-ansible would generate environments for every supported Python and Ansible version combination, resulting in a very large matrix.
-
Open the
tox-ansible.inifile in the collection root and replace its contents with:[ansible] skip = py3.7 py3.8 py3.9 py3.10 py3.11 py3.13 py3.14 2.9 2.10 2.11 2.12 2.13 2.14 2.15 2.16 2.17 2.18 2.19 devel milestone -
Understanding the config:
-
The
skiplist excludes Python versions and Ansible versions that are not available in our environment. This leaves onlypy3.12andansible-core 2.20, keeping the test matrix small and fast. -
You do not need a
tox.inifile — the plugin handles environment creation, dependency installation, and test execution automatically. -
You do not need to define
[testenv:lint]or[testenv:molecule]sections. The plugin creates these for you!
-
Task 3: Explore the auto-generated environments
Now that the config is updated, let’s see what the plugin found in your project. The --ansible flag activates the plugin and -c tox-ansible.ini tells tox to use our configuration file.
-
List all available environments:
tox --ansible -c tox-ansible.ini listObserve the magic: Even though your
tox-ansible.inionly contains a skip list, the plugin scanned your collection and auto-generated test environments. You should see entries like:-
galaxy(Build and validate collection artifact) -
integration-py3.12-2.20(Auto-discovered molecule scenarios) -
sanity-py3.12-2.20(Auto-discovered sanity tests) -
unit-py3.12-2.20(Auto-discovered pytest)The py3.12and2.20reflect the Python and Ansible versions available in your environment. The plugin automatically matched them based on what is installed and what we did not skip.
-
Task 4: Run the tests
Now we let tox orchestrate the execution. Remember to always pass --ansible -c tox-ansible.ini so the plugin is activated with the correct config.
-
Run Sanity Tests:
tox --ansible -c tox-ansible.ini -e sanity-py3.12-2.20Tox creates a virtual environment, installs the required dependencies, and runs
ansible-test sanityagainst your collection. When it finishes, you should see:sanity-py3.12-2.20: OK (38.48=setup[4.34]+cmd[28.34,0.02,5.78] seconds) congratulations :) (38.58 seconds) -
Run Unit Tests:
tox --ansible -c tox-ansible.ini -e unit-py3.12-2.20Expected output:
tests/unit/test_basic.py::test_basic [gw0] [100%] PASSED tests/unit/test_basic.py::test_basic ============================================================== 1 passed in 0.74s ============================================================== unit-py3.12-2.20: OK (32.74=setup[9.41]+cmd[22.03,1.30] seconds) congratulations :) (32.84 seconds) -
Run Integration Tests (Molecule): Instead of typing the long
molecule test -s …command, we use the tox environment.tox --ansible -c tox-ansible.ini -e integration-py3.12-2.20Expected output:
============================================================= 1 skipped in 0.69s ============================================================== integration-py3.12-2.20: OK (32.88=setup[9.27]+cmd[22.34,1.28] seconds) congratulations :) (32.98 seconds)The 1 skippedresult is expected — the scaffoldedtest_integration.pyis a placeholder. The actual integration tests run through Molecule scenarios.This automatically: 1. Creates a fresh virtual environment. 2. Installs Ansible Core 2.20. 3. Installs Molecule and its dependencies. 4. Executes the test scenarios.
Task 5: Build and validate the collection
The galaxy environment builds your collection tarball and runs galaxy-importer to validate it.
-
Run the galaxy environment:
tox --ansible -c tox-ansible.ini -e galaxyExpected output:
...ansible-lint run complete Collection loading complete galaxy: OK (22.00=setup[8.21]+cmd[13.79] seconds) congratulations :) (22.10 seconds)
Troubleshooting
"provided environments not found"
Make sure you are passing both --ansible and -c tox-ansible.ini. Without --ansible, the plugin does not activate and the auto-generated environments won’t exist.
"No environments matched"
If tox --ansible -c tox-ansible.ini list returns no environments:
1. Ensure you are in the directory containing galaxy.yml.
2. Ensure you actually created the tests/unit folder or molecule scenarios in previous modules. The plugin only generates environments for tests that actually exist.
Summary
In this lab, you utilized the tox-ansible plugin to dramatically simplify test automation.
-
Orchestration: You replaced manual
pytest,molecule, andansible-testcommands with a unifiedtoxinterface. -
Auto-discovery: You learned how the plugin scans your collection structure and the
tox-ansible.iniconfig to generate the test matrix automatically. -
Convention over Configuration: You ran sanity, unit, integration, and galaxy validation tests with a single configuration file and no manual environment definitions.
Next steps
With your testing pipeline automated, you are ready to package your work. Click the Next button below to proceed to Lab 3.1 - Creating an Execution Environment with ansible-builder.