Skip to content

Commit 7bae678

Browse files
Add async test runner and guard optional RL dependencies
1 parent 5217b2d commit 7bae678

7 files changed

Lines changed: 85 additions & 41 deletions

conftest.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""Pytest configuration for Mujoco MCP tests."""
2+
3+
from __future__ import annotations
4+
5+
import asyncio
6+
import inspect
7+
8+
import pytest
9+
10+
11+
@pytest.hookimpl(tryfirst=True)
12+
def pytest_pyfunc_call(pyfuncitem: pytest.Item) -> bool | None:
13+
"""Allow ``async def`` tests to run without pytest-asyncio."""
14+
test_func = getattr(pyfuncitem, "obj", None)
15+
if inspect.iscoroutinefunction(test_func):
16+
asyncio.run(test_func(**pyfuncitem.funcargs))
17+
return True
18+
return None

test_advanced_features.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
Tests all new capabilities: controllers, coordination, sensors, RL, benchmarks, visualization
55
"""
66

7+
import importlib.util
78
import time
89
import numpy as np
910
import sys
@@ -12,9 +13,21 @@
1213
import tempfile
1314
import json
1415

16+
import pytest
17+
1518
# Add project to path
1619
sys.path.insert(0, str(Path(__file__).parent / "src"))
1720

21+
missing_optional = [
22+
name for name in ("scipy", "gymnasium") if importlib.util.find_spec(name) is None
23+
]
24+
25+
if missing_optional:
26+
pytest.skip(
27+
"Missing optional dependencies: " + ", ".join(missing_optional),
28+
allow_module_level=True,
29+
)
30+
1831
# Import all advanced modules
1932
from mujoco_mcp.advanced_controllers import (
2033
PIDController,

test_debug.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
#!/usr/bin/env python3
22
"""Debug the action space issue"""
33

4+
import importlib.util
45
import sys
56
from pathlib import Path
67
import numpy as np
78

9+
import pytest
10+
811
# Add src to path for imports
912
sys.path.insert(0, str(Path(__file__).parent / "src"))
1013

14+
if importlib.util.find_spec("gymnasium") is None:
15+
pytest.skip("gymnasium is required for RL integration tests", allow_module_level=True)
16+
1117
from mujoco_mcp.rl_integration import create_balancing_env
1218

1319

test_rl_advanced.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,27 @@
44
Tests policy evaluation, training workflows, and advanced RL features
55
"""
66

7+
import importlib.util
78
import sys
89
import time
910
import numpy as np
1011
import json
1112
from pathlib import Path
1213
from typing import Dict, Any
1314

15+
import pytest
16+
1417
# Add src to path for imports
1518
sys.path.insert(0, str(Path(__file__).parent / "src"))
1619

17-
try:
18-
from mujoco_mcp.rl_integration import (
19-
RLConfig, MuJoCoRLEnvironment, RLTrainer,
20-
ReachingTaskReward, BalancingTaskReward, WalkingTaskReward,
21-
create_reaching_env, create_balancing_env, create_walking_env
22-
)
23-
except ImportError as e:
24-
print(f"❌ Import Error: {e}")
25-
sys.exit(1)
20+
if importlib.util.find_spec("gymnasium") is None:
21+
pytest.skip("gymnasium is required for RL integration tests", allow_module_level=True)
22+
23+
from mujoco_mcp.rl_integration import (
24+
RLConfig, MuJoCoRLEnvironment, RLTrainer,
25+
ReachingTaskReward, BalancingTaskReward, WalkingTaskReward,
26+
create_reaching_env, create_balancing_env, create_walking_env
27+
)
2628

2729
class AdvancedRLTests:
2830
"""Advanced RL functionality tests"""

test_rl_functionality.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,30 @@
44
Tests all aspects of the MuJoCo MCP RL integration
55
"""
66

7+
import importlib.util
78
import sys
89
import time
910
import numpy as np
1011
import logging
1112
from pathlib import Path
1213
from typing import Dict, Any
1314

15+
import pytest
16+
1417
# Add src to path for imports
1518
sys.path.insert(0, str(Path(__file__).parent / "src"))
1619

17-
try:
18-
from mujoco_mcp.rl_integration import (
19-
RLConfig, MuJoCoRLEnvironment, RLTrainer,
20-
ReachingTaskReward, BalancingTaskReward, WalkingTaskReward,
21-
create_reaching_env, create_balancing_env, create_walking_env,
22-
example_training
23-
)
24-
from mujoco_mcp.viewer_client import MuJoCoViewerClient
25-
from mujoco_mcp.simulation import MuJoCoSimulation
26-
except ImportError as e:
27-
print(f"❌ Import Error: {e}")
28-
print("Make sure MuJoCo MCP is properly installed")
29-
sys.exit(1)
20+
if importlib.util.find_spec("gymnasium") is None:
21+
pytest.skip("gymnasium is required for RL integration tests", allow_module_level=True)
22+
23+
from mujoco_mcp.rl_integration import (
24+
RLConfig, MuJoCoRLEnvironment, RLTrainer,
25+
ReachingTaskReward, BalancingTaskReward, WalkingTaskReward,
26+
create_reaching_env, create_balancing_env, create_walking_env,
27+
example_training
28+
)
29+
from mujoco_mcp.viewer_client import MuJoCoViewerClient
30+
from mujoco_mcp.simulation import MuJoCoSimulation
3031

3132
# Configure logging
3233
logging.basicConfig(level=logging.INFO)

test_rl_integration.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
Tests RL functionality with actual MuJoCo physics simulation
55
"""
66

7+
import importlib.util
78
import sys
89
import time
910
import subprocess
@@ -15,19 +16,20 @@
1516
import threading
1617
import logging
1718

19+
import pytest
20+
1821
# Add src to path for imports
1922
sys.path.insert(0, str(Path(__file__).parent / "src"))
2023

21-
try:
22-
from mujoco_mcp.rl_integration import (
23-
RLConfig, MuJoCoRLEnvironment, RLTrainer,
24-
create_reaching_env, create_balancing_env, create_walking_env
25-
)
26-
from mujoco_mcp.viewer_server import MuJoCoViewerServer
27-
from mujoco_mcp.viewer_client import MuJoCoViewerClient
28-
except ImportError as e:
29-
print(f"❌ Import Error: {e}")
30-
sys.exit(1)
24+
if importlib.util.find_spec("gymnasium") is None:
25+
pytest.skip("gymnasium is required for RL integration tests", allow_module_level=True)
26+
27+
from mujoco_mcp.rl_integration import (
28+
RLConfig, MuJoCoRLEnvironment, RLTrainer,
29+
create_reaching_env, create_balancing_env, create_walking_env
30+
)
31+
from mujoco_mcp.viewer_server import MuJoCoViewerServer
32+
from mujoco_mcp.viewer_client import MuJoCoViewerClient
3133

3234
class RLIntegrationTest:
3335
"""Test RL integration with MuJoCo viewer"""

test_rl_simple.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,25 @@
33
Simplified RL Test - Tests core RL functionality without MuJoCo viewer dependency
44
"""
55

6+
import importlib.util
67
import sys
78
import time
89
import numpy as np
910
from pathlib import Path
1011

12+
import pytest
13+
1114
# Add src to path for imports
1215
sys.path.insert(0, str(Path(__file__).parent / "src"))
1316

14-
try:
15-
from mujoco_mcp.rl_integration import (
16-
RLConfig, MuJoCoRLEnvironment, RLTrainer,
17-
create_reaching_env, create_balancing_env, create_walking_env,
18-
example_training
19-
)
20-
except ImportError as e:
21-
print(f"❌ Import Error: {e}")
22-
sys.exit(1)
17+
if importlib.util.find_spec("gymnasium") is None:
18+
pytest.skip("gymnasium is required for RL integration tests", allow_module_level=True)
19+
20+
from mujoco_mcp.rl_integration import (
21+
RLConfig, MuJoCoRLEnvironment, RLTrainer,
22+
create_reaching_env, create_balancing_env, create_walking_env,
23+
example_training
24+
)
2325

2426
def test_rl_core_functionality():
2527
"""Test core RL functionality without MuJoCo viewer"""

0 commit comments

Comments
 (0)