pytest plugin for testing CAD/BIM API code inside live host applications via the RevitDevTool Named Pipe bridge.
Write tests locally with pytest; execution happens inside the host process. Currently supported: Revit and AutoCAD family only. Navisworks, Rhino, Tekla, and other hosts are in progress.
pip install revitdevtool_pytest
# or
uv add revitdevtool_pytest| Requirement | Version |
|---|---|
| Python | >= 3.10 |
| pytest | >= 9.0 |
| pywin32 | >= 311 |
| OS | Windows (Named Pipes) |
| Host | RevitDevTool add-in loaded |
host_name |
Application | Pipe prefix |
|---|---|---|
revit |
Autodesk Revit | Revit |
autocad |
AutoCAD | AutoCad |
civil3d |
Civil 3D | Civil3D |
plant3d |
Plant 3D | Plant3D |
acadarch |
AutoCAD Architecture | AcadArch |
acadmech |
AutoCAD Mechanical | AcadMech |
acadmep |
AutoCAD MEP | AcadMep |
acadelec |
AutoCAD Electrical | AcadElec |
acadmap3d |
AutoCAD Map 3D | AcadMap3D |
host_name |
Application | Status |
|---|---|---|
navisworks |
Navisworks | Not validated |
rhino |
Rhino | Not validated |
tekla |
Tekla Structures | Not validated |
The plugin registry may list additional names for future work. Treat them as experimental until documented here as Supported today.
The plugin connects to the pytest/control pipe:
DevTools_{Host}_{Version}_{PID}
Examples: DevTools_Revit_2025_12345, DevTools_AutoCad_2026_7890
MCP clients use a separate pipe: DevToolsMcp_{Host}_{Version}_{PID}. Do not point pytest at an MCP pipe.
uv init my-host-tests && cd my-host-tests
uv add revitdevtool_pytest pytestpyproject.toml:
[tool.pytest.ini_options]
host_name = "revit"
host_version = "2025"
force_launch = false
per_test_timeout = "60"
launch_timeout = "180"tests/conftest.py:
import pytest
@pytest.fixture(scope="session")
def revit_uiapp():
return __revit__
@pytest.fixture(scope="session")
def revit_doc(revit_uiapp):
return revit_uiapp.ActiveUIDocument.Documenttests/test_smoke.py:
def test_active_view(revit_doc):
assert revit_doc.ActiveView is not Noneuv run pytest -v| Option | Default | Description |
|---|---|---|
host_name |
"revit" |
Target host — use Supported today names only. |
host_version |
— | Version string ("2025", "8.0", …). Required for launch. |
force_launch |
false |
Force a new host instance (skip reuse). Requires host_version. |
per_test_timeout |
"60" |
Per-test budget (seconds). The tests/run pipe wait is this × collected tests. |
launch_timeout |
"180" |
Wait for host pipe after launch (seconds). |
host_pipe |
— | Explicit pipe name (skip discovery). |
CLI flags override INI: --host, --host-version, --force-launch, --per-test-timeout, --launch-timeout, --host-pipe.
force_launch = false(default): scan forDevTools_*pipes matchinghost_name/host_version, reuse a free instance (suite leasing), or reconnect to a leased PID.- No matching instance: auto-launch host when
host_versionis set (unless--host-pipepins an existing pipe). force_launch = true: always spawn a new process and wait for its pipe.
Captured print() from in-host tests is shown for passing tests (same as -rP). No extra flags needed.
- Put host API imports inside functions — collection runs on your machine, execution in the host.
- Use fixtures for
__revit__, documents, and rollback helpers. - Declare suite dependencies with PEP 723 in
conftest.py; RevitDevTool installs them before run:
# /// script
# dependencies = ["numpy>=2.0", "polars>=1.0"]
# ///@pytest.fixture
def revit_auto_rollback(revit_transaction_service):
revit_transaction_service.StartChanges()
try:
yield revit_transaction_service
finally:
revit_transaction_service.RevertChanges()- Local pytest collects tests.
- Plugin connects to
DevTools_{Host}_{Version}_{PID}. - Node IDs sent via JSON-RPC method
tests/run(BridgeMessagelength-prefixed frames). - Host runs
PytestRunner.pyembedded in RevitDevTool (PytestExecutionServiceon main thread). - Results and optional progress notifications return to the client.
- Plugin maps
CaseResult→ standard pytest reports.
Clone and run integration tests against a live host:
cd RevitDevTool.PyTest
uv run pytest -v # Revit suite (default)
uv run pytest tests/Revit/test_smoke.py -v
uv run pytest --host civil3d --host-version 2026 # after switching testpaths/host in pyproject.toml| Path | Purpose |
|---|---|
src/revitdevtool_pytest/ |
Plugin source (published wheel) |
tests/Revit/ |
Revit integration tests + schedule/ helpers |
tests/Civil3d/ |
Civil 3D / AutoCAD API tests |
Revit suite settings in pyproject.toml: testpaths = ["tests/Revit"], pythonpath = ["tests/Revit"] for local schedule imports.
Optional env: REVIT_TEST_MODEL_PATH — path to .rvt for revit_doc fixture (default F:\Project1.rvt).
VS Code / Cursor — python.testing.pytestEnabled: true. Plugin detects vscode_pytest / TEST_RUN_PIPE and disables CLI streaming to avoid duplicate tree entries.
PyCharm — enable pytest as test runner.