- https://github.com/devopsschool-demo-labs-projects/ansible-molecule-testing
- https://github.com/devopsschool-demo-labs-projects/ansible-molecule-example
- https://github.com/devops-school/molecule-ansible-playbook-testing
What is Unit Testing in Ansible?
Unit testing in Ansible refers to testing the smallest pieces of code within Ansible—primarily custom modules, plugins, or Ansible-related Python code—in isolation from the rest of the system. Unlike playbook testing (which is more integration or functional testing), unit tests focus on verifying the logic and expected outcomes of functions or methods without requiring actual servers or external systems.
How Does Unit Testing Work in Ansible?
- Scope: Unit tests target specific functions in Ansible modules/utilities. They are Python-based and are executed independently of target infrastructure.
- Method: You write Python test scripts that mock dependencies and check expected behaviors (for example, does the module return the right result for specific input? Does it call the correct APIs?).
- Framework: Ansible leverages standard Python tools like
pytest
orunittest
, and provides theansible-test
command-line tool to execute unit tests in a standardized, continuous integration-friendly way. - Location: Unit tests for the Ansible core project or custom collections are typically placed in a
tests/unit/
directory and mirror the structure of the code under test.
Why Use Unit Tests?
- Faster feedback than integration tests.
- Do not require target servers or real infrastructure.
- Help catch logical and regression bugs in module code early.
- Force you to design testable (often better) code.
How to Do Unit Testing in Ansible: Step by Step
Below is a practical and minimal workflow to write and run unit tests for Ansible modules or Python code.
1. Create or Identify the Code to Test
Suppose you have a custom module, e.g. my_module.py
, or a utility function.
2. Create a Test Script
- Place it in
tests/unit/modules/test_my_module.py
or a similar path for your project. - Use
pytest
orunittest
in Python.
Example:
pythonimport unittest
from ansible.modules.my_namespace import my_module
class TestMyModule(unittest.TestCase):
def test_add(self):
result = my_module.add(2, 3)
self.assertEqual(result, 5)
def test_fail_case(self):
with self.assertRaises(ValueError):
my_module.add('a', 1)
Or with a simple function-based style (for small cases):
pythondef test_add():
from ansible.modules.my_namespace import my_module
assert my_module.add(2, 3) == 5
3. Use Mocking for External Dependencies
For modules interacting with systems/network, mock those calls to make tests independent of actual systems.
4. Run the Unit Tests
- Activate your development environment.
- Use the standard Ansible test runner (inside your ansible repo): text
source hacking/env-setup ansible-test units --docker -v
Or, for a specific file/module: textansible-test units --docker -v my_module
- Or, run with pytest directly if set up that way: text
pytest tests/unit/modules/test_my_module.py
5. Interpret Results
Green = tests passed. Red = test or logic failure (with a Python traceback showing what failed and why).
6. Refine and Repeat
Add more test functions covering different logic branches, error cases, and edge cases.
Summary Table: Unit Test Steps for Ansible Modules
Step | What to Do |
---|---|
1 | Write your Ansible module/Python function |
2 | Write Python unit test scripts (test_*.py) |
3 | Use mocking for any system-level or network functions |
4 | Run tests using ansible-test units or pytest |
5 | Fix code/tests based on failures, repeat cycle |
References for Further Reading
- [Ansible’s official unit testing documentation]
- [Practical unit test project examples]
You do not use unit tests for playbooks/roles directly—instead, use playbook integration testing tools like Molecule or full-featured CI workflows.
In short:
Unit testing in Ansible means writing small Python tests targeting your custom modules/utilities, running them with ansible-test units
or pytest
, and using mocks where needed—resulting in quick, automated checks of your Ansible code’s core logic before running on actual servers.
Unit testing in Ansible is all about verifying the smallest, testable parts of your Ansible automation (like roles, modules, and tasks) in isolation before running them in production. Unlike full integration testing (which runs an entire playbook), unit tests are meant to catch mistakes and enforce code quality in your Ansible content early and often.
What is Unit Testing in Ansible?
- Definition:
Unit testing in Ansible is the practice of testing individual roles, modules, or even specific tasks—without running the whole playbook against real infrastructure. - Goal:
Quickly catch errors, syntax issues, bad logic, and unintended changes by testing code in isolation. - Tools:
The most common and recommended tool for unit testing Ansible content is Ansible Test (built into ansible-core and Ansible collections).
Other popular frameworks: Molecule (for role/collection testing), pytest, Testinfra, and YAML linting.
How Does Unit Testing Work in Ansible?
- Ansible code is split into units like roles, modules, or plugins.
- Each unit is tested with small, focused tests—often using Python, YAML, or Ansible’s built-in test tools.
- Ansible Test runs these tests automatically.
- For roles, Molecule (plus pytest/testinfra) is often used for deeper tests, including syntax, linting, and idempotence checks.
Step-by-Step: Unit Testing in Ansible
Below are two approaches:
- A. For Ansible Collections (using
ansible-test
) - B. For Roles (using Molecule + Testinfra)
A. Unit Testing Ansible Collections (with ansible-test
)
Step 1: Install Requirements
- Ensure you have Ansible and
ansible-test
(included with ansible-core and ansible-base).
pip install ansible-core
Step 2: Structure Your Collection
If you have a collection (the modern way to develop reusable Ansible code), tests live in tests/unit/
.
Example structure:
my_collection/
plugins/
modules/
mymodule.py
tests/
unit/
plugins/
modules/
test_mymodule.py
Step 3: Write a Unit Test
A test for a custom module might look like this (test_mymodule.py
):
from ansible.modules.my_collection.mymodule import main
def test_some_logic():
# Simulate the module's logic and assert output
pass
Code language: PHP (php)
Step 4: Run Ansible Test
From your collection root:
ansible-test units
This will discover and run all unit tests in tests/unit/
.
B. Unit Testing Roles (with Molecule + Testinfra)
Molecule can run basic role checks, linting, and testinfra-based verification (often in containers or VMs).
Step 1: Install Molecule and Testinfra
pip install "molecule[docker]" testinfra ansible-lint
Code language: JavaScript (javascript)
Step 2: Initialize Molecule in Your Role
cd myrole
molecule init scenario -r myrole -d docker
This creates a molecule/
folder with default config and tests.
Step 3: Write Unit Tests in molecule/default/tests/test_default.py
Example (checks if nginx is installed):
def test_nginx_installed(host):
nginx = host.package("nginx")
assert nginx.is_installed
Code language: JavaScript (javascript)
Step 4: Run Molecule Test
molecule test
This will:
- Lint your role
- Create a container/VM
- Apply your role
- Run unit tests
- Destroy the test environment
C. Linting and Syntax Checking (Recommended for ALL Ansible Code)
- ansible-lint: Lint all playbooks/roles for best practices:
ansible-lint playbook.yml
- ansible-playbook –syntax-check: Catch syntax errors quickly.
ansible-playbook --syntax-check playbook.yml
Summary Table
Tool | Purpose | What It Tests |
---|---|---|
ansible-test | Unit test modules/plugins | Ansible collection plugins/modules |
molecule | Role testing (all-in-one) | Roles: syntax, lint, behavior, idempotence |
testinfra | Python host tests | Verifies end state inside VMs/CTs |
ansible-lint | Style and best practices | YAML and role/playbook structure |
Best Practices
- Start with
ansible-lint
and--syntax-check
for ALL playbooks/roles. - For custom modules/plugins/collections, use
ansible-test units
. - For roles: use Molecule + Testinfra for behavior/unit tests.
- Integrate tests into your CI/CD pipeline for every code change.
References
I’m a DevOps/SRE/DevSecOps/Cloud Expert passionate about sharing knowledge and experiences. I have worked at Cotocus. I share tech blog at DevOps School, travel stories at Holiday Landmark, stock market tips at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow , and SEO strategies at Wizbrand.
Do you want to learn Quantum Computing?
Please find my social handles as below;
Rajesh Kumar Personal Website
Rajesh Kumar at YOUTUBE
Rajesh Kumar at INSTAGRAM
Rajesh Kumar at X
Rajesh Kumar at FACEBOOK
Rajesh Kumar at LINKEDIN
Rajesh Kumar at WIZBRAND