Skip to content

Pytest Integration

Nicolas Couture edited this page Apr 19, 2026 · 2 revisions

Testing with Pytest

Modern Python projects benefit significantly from using pytest fixtures to manage the lifecycle of the mock server.

Recommended Pattern

Create a conftest.py to manage the global Twisted reactor and individual server instances.

tests/conftest.py

import pytest
import MockSSH
from twisted.internet import reactor
from threading import Thread
import time

@pytest.fixture(scope="session", autouse=True)
def twisted_reactor():
    """Starts the reactor in a background thread once per session."""
    if not reactor.running:
        t = Thread(target=reactor.run, args=(False,))
        t.daemon = True
        t.start()
        time.sleep(0.5) # Give it a moment to start
    yield reactor

Module-Level Server Fixture

@pytest.fixture(scope="module")
def mock_server():
    users = {"admin": "pass"}
    # Use port 0 to let the OS assign an available port
    server = MockSSH.startThreadedServer(
        commands,
        port=0,
        **users
    )
    yield server
    MockSSH.stopThreadedServer(server)

@pytest.fixture
def ssh_client(mock_server):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # Retrieve the dynamically assigned port from the server object
    ssh.connect("127.0.0.1", port=mock_server.getHost().port, username="admin", password="pass")
    yield ssh
    ssh.close()

Native Assertions

With pytest, you can use standard assert statements instead of the complex unittest methods, leading to much more readable test code.

Clone this wiki locally