Why Roles Need Automated Testing
Without automated testing, verifying that an Ansible role actually works means manually spinning up a VM, running the playbook, eyeballing the result, and tearing it down — a slow, error-prone loop that most people skip after the first few iterations. Molecule automates this entire cycle: it provisions one or more test instances (via Docker, Vagrant, or a cloud driver), applies the role, runs verification checks, and destroys the instances, all triggered by a single molecule test command that can run in CI on every commit.
Cricket analogy: It's like the difference between a bowler manually asking a teammate to eyeball their action after every delivery versus a biomechanics lab running the same automated motion-capture analysis on every single ball bowled in the nets.
The Molecule Test Sequence
A default Molecule scenario runs a fixed sequence of steps: dependency (install role dependencies), create (provision the test instance(s)), prepare (optional pre-converge setup), converge (actually run the role, the core step), idempotence (run converge again and assert zero changes), verify (run assertions, typically written with Ansible tasks or Testinfra/pytest), and destroy (tear down the instance). Running molecule converge alone during active development lets you iterate quickly without paying the cost of the full destroy/create cycle every time, while molecule test runs the complete sequence end-to-end, exactly as CI would.
Cricket analogy: It's like a full day-night Test match's fixed sequence — toss, first innings, second innings, follow-on decision, declaration, result — versus a net session where a batter just repeats the same drill (converge) without running the full match sequence each time.
# molecule/default/molecule.yml
driver:
name: docker
platforms:
- name: instance
image: geerlingguy/docker-ubuntu2204-ansible:latest
pre_build_image: true
provisioner:
name: ansible
verifier:
name: ansibleAdd a dedicated idempotence step to CI (molecule test already includes it) so a role that quietly reports 'changed' on a second converge — a common regression when someone adds a raw shell task — fails the build immediately.
Writing Verify Assertions
The verify step is where you assert the role produced the intended real-world outcome, not just that tasks ran without error — for example, checking that the Nginx service is actually listening on port 80, that the config file has the expected permissions, or that a specific string appears in a generated template output. Molecule's default verifier lets you write these checks as ordinary Ansible tasks using modules like ansible.builtin.uri, ansible.builtin.stat, and ansible.builtin.assert, which keeps the testing language consistent with the role itself rather than requiring a second toolchain.
Cricket analogy: It's like a coach checking not just that a bowler completed the over, but that the final delivery actually clipped the top of off stump — verifying the intended outcome, not just that the action occurred.
A verify step that only checks 'the playbook exited zero' provides almost no real coverage — always add concrete assertions about the resulting system state, such as service status, listening ports, or file contents.
- Molecule automates the create-converge-verify-destroy test cycle for Ansible roles, replacing slow manual VM testing.
- The full sequence is: dependency, create, prepare, converge, idempotence, verify, destroy.
- molecule converge is used for fast iteration during development; molecule test runs the full CI-equivalent sequence.
- The idempotence step re-runs converge and asserts zero changes, catching non-idempotent tasks automatically.
- molecule.yml configures the driver (e.g. Docker), platforms (test images), provisioner, and verifier.
- The verify step should assert real system outcomes (service state, ports, file contents), not just exit codes.
- Molecule's default verifier lets you write verify checks as ordinary Ansible tasks, reusing the same toolchain as the role.
Practice what you learned
1. What is the correct default order of Molecule's test sequence?
2. What does the idempotence step in Molecule check?
3. Which command is best for fast local iteration during role development?
4. What should a good verify step assert?
Was this page helpful?
You May Also Like
Reusable Role Design
Practical principles for writing Ansible roles that are genuinely reusable across projects, teams, and environments.
Ansible Roles Explained
Learn what Ansible roles are, why they exist, and how their standard directory layout lets you package reusable, shareable automation.
Role Dependencies
Learn how to declare dependencies between Ansible roles using meta/main.yml, and understand ordering, deduplication, and pitfalls.
Ansible Galaxy and Collections
Understand Ansible Galaxy as a content hub and Collections as the modern packaging format for roles, modules, and plugins.
Related Reading
Related Study Notes in DevOps
Browse all study notesNginx Study Notes
DevOps · 30 topics
DevOpsAdvanced Kubernetes Study Notes
Kubernetes · 30 topics
DevOpsAdvanced Bash Scripting Study Notes
Bash · 30 topics
DevOpsApache Kafka Study Notes
Kafka · 30 topics
DevOpsDocker & Kubernetes Study Notes
YAML · 40 topics
DevOpsCI/CD Tools & Pipelines Study Notes
YAML · 37 topics