Skip to content

Testing PyTest Bridge

Truong Giang Vu edited this page May 31, 2026 · 1 revision

PyTest Bridge

Run pytest tests inside live Revit, AutoCAD, or Civil 3D instances via Named Pipe.

Source code: RevitDevTool.PyTest (separate repo) | PyPI: revitdevtool_pytest | Architecture: docs/PyTest/README.md

Why It Exists

Host API code cannot be fully tested from a normal external Python process because API calls need host context (active document, transactions, Revit/AutoCAD runtime). The bridge lets pytest collect tests locally, then execute them remotely inside the running host.

How It Works

Local pytest (collect) → Named Pipe → Host (PytestRunner.py) → Results → Local pytest (report)
  1. pytest discovers and collects tests locally
  2. Plugin connects to the host via Named Pipe ({Host}_{Version}_{PID})
  3. Test nodeids are sent to the host's PytestRunner.py
  4. Tests execute inside the host's Python.NET environment with full API access
  5. Results (pass/fail/skip, stdout, tracebacks) return via pipe
  6. Plugin maps results back to standard pytest reports

Installation

pip install revitdevtool_pytest

Configuration

Add to pyproject.toml:

[tool.pytest.ini_options]
host_name = "revit"         # revit, autocad, civil3d, plant3d, etc.
host_version = "2025"       # version string (2025, 8.0, etc.)
host_launch = false         # true = always launch new instance
host_timeout = "60"         # per-test timeout (seconds)
host_launch_timeout = "180" # startup wait (seconds)

Supported Hosts

Host Name Application Pipe Prefix
revit Autodesk Revit Revit
autocad AutoCAD AutoCad
civil3d Civil 3D Civil3D
plant3d Plant 3D Plant3D
Any name Any DevToolsPipeServer host Uses name as prefix

Running Tests

# Default (uses pyproject.toml config):
pytest -v

# Override host and version:
pytest --host autocad --host-version=2026 -v

# Civil 3D:
pytest --host civil3d --host-version=2026 -v

# Force-launch a new instance:
pytest --host-launch --host-version=2025 -v

# Connect to a specific pipe:
pytest --host-pipe=Revit_2025_12345 -v

Writing Tests

Revit Example

# conftest.py
import pytest

@pytest.fixture(scope="session")
def revit_uiapp():
    return __revit__  # noqa: F821

@pytest.fixture(scope="session")
def revit_doc(revit_uiapp):
    return revit_uiapp.ActiveUIDocument.Document
# test_walls.py
def test_wall_count(revit_doc):
    from Autodesk.Revit.DB import FilteredElementCollector, BuiltInCategory
    walls = list(
        FilteredElementCollector(revit_doc)
        .OfCategory(BuiltInCategory.OST_Walls)
        .WhereElementIsNotElementType()
    )
    print(f"Found {len(walls)} walls")
    assert len(walls) > 0

AutoCAD / Civil 3D Example

# conftest.py
import pytest

@pytest.fixture(scope="session")
def acad_app():
    from Autodesk.AutoCAD.ApplicationServices.Core import Application
    return Application

@pytest.fixture(scope="session")
def acad_doc(acad_app):
    return acad_app.DocumentManager.MdiActiveDocument

@pytest.fixture(scope="session")
def acad_db(acad_doc):
    return acad_doc.Database
# test_layers.py
def test_layer_count(acad_db, acad_transaction):
    from Autodesk.AutoCAD.DatabaseServices import LayerTable, OpenMode
    lt = acad_transaction.GetObject(acad_db.LayerTableId, OpenMode.ForRead)
    count = sum(1 for _ in lt)
    print(f"Found {count} layers")
    assert count > 0

Key Rules

  • All host/.NET imports must be inside function bodies (lazy imports)
  • Revit: __revit__ builtin is injected by RevitDevTool — access via fixtures
  • AutoCAD: no builtin injection — use static Application class directly
  • Tests run on the host's main thread sequentially

PEP 723 Dependencies

Declare dependencies in conftest.py — RevitDevTool auto-installs them:

# /// script
# dependencies = ["numpy>=2.0", "polars>=1.0"]
# ///

Print Output

print() inside tests is automatically captured and displayed for both passing and failing tests. No extra flags needed.

IDE Integration

VS Code / Cursor

{
    "python.testing.pytestEnabled": true,
    "python.testing.pytestArgs": ["tests"]
}

PyCharm

Enable pytest as the test runner. The plugin auto-detects IDE adapters and adjusts streaming to avoid duplicate results.

Troubleshooting

"Could not connect to host"

  1. Verify the host is running with RevitDevTool installed
  2. Check pipe exists: ls //./pipe/ | findstr Revit (or AutoCad, Civil3D)
  3. Try explicit pipe: pytest --host-pipe=Revit_2025_<pid>
  4. Check --host-version matches running instance

"Suite is already running in another pytest process"

Another pytest session holds the suite mutex. Kill the other process or wait.

Tests timeout

Increase timeout: pytest --host-timeout=120

Clone this wiki locally