pytest-clab
pytest-clab is authored by Thomas Bamihas, governed as a benevolent dictatorship, and distributed under the Apache 2.0 license.
Introduction
While containerlab simplifies spinning up network topologies, integrating it into test workflows still requires boilerplate for deployment, teardown, and node interaction. This plugin provides a convenient pytest fixture to manage containerlab topologies with automatic lifecycle management.
Features
- Lab lifecycle management: Deploy and destroy containerlab topologies directly from pytest.
- Multiple lab support: Interact with multiple labs within a single pytest session, for tests that depend on more than one topology.
- Topology readiness checks: Verify dependent labs are ready before running tests.
- Dynamic node inventory: Retrieve node addresses and connection parameters at test runtime instead of hardcoding them in tests.
- Containerlab CLI access: Run containerlab commands from tests for operations not covered by plugin helpers.
Installation
pip install pytest-clab
Requirements: containerlab CLI must be installed and in PATH.
Quickstart
@pytest.fixture(scope="session")
def lab(clab):
return clab("topology.clab.yaml")
@pytest.mark.parametrize("node_name", ["node1", "node2"])
def test_mgmt_interface_status(lab, node_name):
# GIVEN a lab node
node = lab.nodes[node_name]
# GIVEN netmiko params
params = {
"host": node.ipv4_address,
"username": os.getenv("SSH_USERNAME"),
"password": os.getenv("SSH_PASSWORD"),
"device_type": "nokia_srl",
}
# WHEN fetching mgmt status
with netmiko.ConnectHandler(**params) as conn:
output = conn.send_command("show interface mgmt0 brief")
# THEN expect mgmt0 to be up
assert "up" in output
Working with Topologies and Nodes
ClabTopology
The clab fixture is a factory that creates ClabTopology instances.
Properties:
name- Lab name as reported by containerlabtopology_path- Path to the topology YAML filenodes- Collection of nodes
Methods:
cmd(command, parse_json=False)- Execute any containerlab command, optionally parse JSON output
output = lab.cmd(f"inspect -t {lab.topology_path} -f json", parse_json=True)
Node Startup Readiness
The plugin automatically polls containerlab inspect and returns only after all nodes report state: "running".
command_timeoutcontrols timeout per containerlab CLI call.startup_timeoutcontrols total startup polling budget.
Service-level readiness (SSH, NETCONF, gNMI, app-level) checks are environment-specific and performed in test logic.
ClabNodes
The nodes property is a collection that supports flexible access patterns.
Methods:
lab.nodes["name"]- Access a node by short name"name" in lab.nodes- Check if a node existslen(lab.nodes)- Get the number of nodesfor node in lab.nodes- Iterate over all nodesfilter_by_kind(kind)- Filter nodes by kind
for node in lab.nodes:
print(node.short_name, node.ipv4_address)
ClabNode
Each node is an immutable dataclass with the following attributes.
Attributes:
short_name- Node name without lab prefix (e.g., "leaf1")name- Full container name (e.g., "clab-mylab-leaf1")lab_name- Name of the labkind- Node kind (e.g., "linux", "nokia_srlinux")image- Container imagestate- Container state (e.g., "running")status- Container status from containerlab (e.g., "healthy")ipv4_address- Management IPv4 addressipv6_address- Management IPv6 addresscontainer_id- Docker container IDproperties- Dictionary containing additional containerlab node properties not listed above
node = lab.nodes["leaf1"]
print(f"{node.short_name} ({node.kind}): {node.ipv4_address}")
Examples
Keep Running Mode
@pytest.fixture(scope="session")
def lab(clab):
return clab("topology.clab.yml", keep_running=True)
JSON Output
def test_json_output(lab):
result = lab.cmd("version -j", parse_json=True)
assert isinstance(result, dict)
Filter by Node Kind
def test_filter_nodes(lab):
srlinux_nodes = lab.nodes.filter_by_kind("nokia_srlinux")
linux_nodes = lab.nodes.filter_by_kind("linux")
assert len(srlinux_nodes) + len(linux_nodes) == len(lab.nodes)
Dynamic Validation Example
This example uses subtests for per-peer test reporting.
def test_bgp_neighbors(lab, subtests):
node = lab.nodes["router1"]
# Use any library to connect to the node (e.g., ncclient, scrapli, netmiko)
with connect(host=node.ipv4_address, ...) as conn:
neighbors = conn.get(filter=BGP_NEIGHBOR_FILTER).data_xml
for neighbor in neighbors:
with subtests.test(peer=neighbor.find("peer-address").text):
assert neighbor.find("state").text == "established"
Configuration
Environment Variables
CONTAINERLAB_EXECUTABLE
Path to containerlab executable
(default: containerlab)
CONTAINERLAB_EXECUTABLE=/usr/local/bin/clab pytest
Fixture Parameters
topology:
Path to containerlab topology YAML file
(required)
lab = clab("topology.clab.yml")
sudo:
Run containerlab commands with sudo
(default: False)
lab = clab("topology.clab.yml", sudo=True)
keep_running:
Keep lab running at session end
(default: False)
lab = clab("topology.clab.yml", keep_running=True)
command_timeout:
Timeout in seconds for each containerlab command
(default: 300)
lab = clab("topology.clab.yml", command_timeout=600)
startup_timeout:
Timeout in seconds for startup-state polling
(default: 30)
lab = clab("topology.clab.yml", startup_timeout=60)
Exceptions
The plugin provides a hierarchy of exceptions for error handling:
ClabError: Base exception for all pytest-clab errorsTopologyNotFoundError: Topology file does not existContainerlabNotFoundError: containerlab executable not found in PATHDeploymentError: Topology deployment failedNodeFailedError: A node entered a terminal state (exited, dead) during startup
InspectError: Failed to inspect running topologyCommandError: A containerlab command failed
Versioning
Releases will follow semantic versioning (major.minor.patch). Before 1.0.0, breaking changes can be included in a minor release, therefore we highly recommend pinning this package.
Contributing
Suggest a feature or report a bug. Read our developer guide.
License
pytest-clab is distributed under the Apache 2.0 license.
Metadata
Release files for pytest-clab 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pytest_clab-0.1.3.tar.gz | 10.8 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_clab-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.2 kB
Release files / pytest_clab-0.1.3.tar.gz
| Download URL | pytest_clab-0.1.3.tar.gz |
|---|---|
| Size | 10.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
86647d4583e0af740bb4403486d4fd43f5ffe6fe0ba54e45f4e470771c9faab3
|
|
BLAKE2b-256 checksum How to use checksums |
41e5bdd951eb10cc38ea914bc88b528be1c26163a2ade78748372af1a6086109
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 2, 2026.
Transparency logRelease files / pytest_clab-0.1.3-py3-none-any.whl
| Download URL | pytest_clab-0.1.3-py3-none-any.whl |
|---|---|
| Size | 17.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6cd66a052238ab2a5bee110cf1fa51ac23fc0f39c96cc5e78d6df2173499423f
|
|
BLAKE2b-256 checksum How to use checksums |
8c856d21f9f689cc53215a5d59e4e040d8c9afc4e57dd19c57f7db969bee5ea3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 2, 2026.
Transparency logSecurity for pytest-clab 0.1.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for pytest_clab-0.1.3.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 2, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.