pytest-testinfra
pytest-testinfra is a Python library and a pytest plugin that enables you to write unit tests in Python to verify the actual state of your servers or other infrastructure components. It acts as a Serverspec equivalent in Python, allowing you to test configurations managed by tools like Ansible, Puppet, or Chef. The current version is 10.2.2. The project recently announced it is not actively maintained, which may lead to slower responses to issues and pull requests.
Warnings
- breaking Python 3.9 or newer is now required. Previous versions of pytest-testinfra supported older Python releases (e.g., Python 3.6 support was dropped in v7.0.0, and Python 3.9 became mandatory in v8.1.0).
- breaking The package was renamed from 'testinfra' to 'pytest-testinfra' in version 6.0.0. Users with 'testinfra' in their `requirements.txt` or import statements needed to update. A dummy 'testinfra' package was available for transition but should not be relied upon.
- gotcha The project is currently not actively maintained. Responses to issues or pull requests may be delayed for several months. This means new features, bug fixes, or compatibility updates might be slow or require community contributions.
- gotcha When using `pytest-testinfra` for remote execution, direct calls to certain Python libraries (e.g., `requests`) via the `host` fixture might not work as expected. The remote environment often provides a more basic wrapper, not a full Python interpreter capable of running arbitrary modules directly.
- gotcha Accessing Ansible inventory variables for *other* hosts (e.g., `hostvars[other_host]`) or global `group_vars` directly through the `host` fixture can be complicated or not directly supported. `host.ansible.get_variables()` primarily provides variables for the currently tested host.
Install
-
pip install pytest-testinfra
Imports
- pytest
import pytest # The 'host' fixture is provided automatically by pytest-testinfra
Quickstart
import pytest
def test_passwd_file(host):
passwd = host.file("/etc/passwd")
assert passwd.contains("root")
assert passwd.user == "root"
assert passwd.group == "root"
assert passwd.mode == 0o644
def test_nginx_is_installed(host):
# Requires nginx to be present on the target host
nginx = host.package("nginx")
assert nginx.is_installed
assert nginx.version.startswith("1.")
def test_nginx_running_and_enabled(host):
# Requires nginx service to be present on the target host
nginx = host.service("nginx")
assert nginx.is_running
assert nginx.is_enabled
# To run this, save as e.g., test_myinfra.py and execute:
# pytest test_myinfra.py --connection=local
# For remote host:
# pytest test_myinfra.py --host=ssh://user@your-remote-host --sudo --connection=ssh