Upgrade & Secure Your Future with DevOps, SRE, DevSecOps, MLOps!

We spend hours scrolling social media and waste money on things we forget, but won’t spend 30 minutes a day earning certifications that can change our lives.
Master in DevOps, SRE, DevSecOps & MLOps by DevOpsSchool!

Learn from Guru Rajesh Kumar and double your salary in just one year.


Get Started Now!

Ansible: Unit Testing in Ansible?

  • 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 or unittest, and provides the ansible-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 or unittest 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): textsource 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: textpytest 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

StepWhat to Do
1Write your Ansible module/Python function
2Write Python unit test scripts (test_*.py)
3Use mocking for any system-level or network functions
4Run tests using ansible-test units or pytest
5Fix 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

ToolPurposeWhat It Tests
ansible-testUnit test modules/pluginsAnsible collection plugins/modules
moleculeRole testing (all-in-one)Roles: syntax, lint, behavior, idempotence
testinfraPython host testsVerifies end state inside VMs/CTs
ansible-lintStyle and best practicesYAML 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

Subscribe
Notify of
guest
0 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments

Certification Courses

DevOpsSchool has introduced a series of professional certification courses designed to enhance your skills and expertise in cutting-edge technologies and methodologies. Whether you are aiming to excel in development, security, or operations, these certifications provide a comprehensive learning experience. Explore the following programs:

DevOps Certification, SRE Certification, and DevSecOps Certification by DevOpsSchool

Explore our DevOps Certification, SRE Certification, and DevSecOps Certification programs at DevOpsSchool. Gain the expertise needed to excel in your career with hands-on training and globally recognized certifications.

0
Would love your thoughts, please comment.x
()
x