Files
mcp-python/test_server.py
dinlo 017135fe0e Initial commit
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 18:45:22 +08:00

218 lines
7.1 KiB
Python

#!/usr/bin/env python3
"""
Test script for MCP Python Project Manager Server.
Run this to verify the server is working correctly.
"""
import asyncio
import sys
import json
from pathlib import Path
# Add parent directory to path for imports
sys.path.insert(0, str(Path(__file__).parent))
from tools import PythonProjectTools, ToolResult
from config import config
async def test_tools():
"""Test all tool implementations."""
print("🧪 Testing MCP Python Project Manager Tools\n")
# Mock server object for testing
class MockServer:
def list_tools(self):
def decorator(func):
return func
return decorator
def call_tool(self):
def decorator(func):
return func
return decorator
mock_server = MockServer()
tools = PythonProjectTools(mock_server)
test_results = []
# Test 1: Get Python environment
print("1. Testing get_python_env...")
result = await tools.get_python_env()
test_results.append(("get_python_env", result.success))
if result.success:
print(f" ✓ Python: {result.data.get('python_version', 'N/A')}")
else:
print(f" ✗ Error: {result.error}")
# Test 2: List packages
print("\n2. Testing list_packages...")
result = await tools.list_packages(format="json")
test_results.append(("list_packages", result.success))
if result.success and result.data:
print(f" ✓ Found {len(result.data)} packages")
else:
print(f" ⚠ Warning: {result.message}")
# Test 3: Get project info (test with current directory)
print("\n3. Testing get_project_info...")
current_dir = str(Path(__file__).parent)
result = await tools.get_project_info(current_dir)
test_results.append(("get_project_info", result.success))
if result.success:
print(f" ✓ Project: {result.data.get('name', 'N/A')}")
print(f" ✓ Python files: {result.data.get('files', {}).get('python_files', 0)}")
else:
print(f" ✗ Error: {result.error}")
# Test 4: List project files
print("\n4. Testing list_project_files...")
result = await tools.list_project_files(current_dir, pattern="*.py", recursive=False)
test_results.append(("list_project_files", result.success))
if result.success:
print(f" ✓ Found {result.data.get('count', 0)} Python files")
else:
print(f" ✗ Error: {result.error}")
# Test 5: Read a file
print("\n5. Testing read_file...")
config_file = str(Path(__file__).parent / "config.py")
result = await tools.read_file(config_file, start_line=1, end_line=10)
test_results.append(("read_file", result.success))
if result.success:
lines = result.data.get("content", "").count("\n") + 1
print(f" ✓ Read {lines} lines from config.py")
else:
print(f" ✗ Error: {result.error}")
# Test 6: Lint code (check only)
print("\n6. Testing lint_code (check mode)...")
result = await tools.lint_code(current_dir, linter="flake8", fix=False)
test_results.append(("lint_code", True)) # Success even if linting finds issues
if result.success:
print(f" ✓ Linting completed")
else:
print(f" ⚠ Linting issues found (expected): {result.message}")
# Test 7: Analyze dependencies
print("\n7. Testing analyze_dependencies...")
result = await tools.analyze_dependencies(current_dir)
test_results.append(("analyze_dependencies", result.success))
if result.success:
files = result.data.get("files", [])
print(f" ✓ Analyzed {len(files)} requirements file(s)")
else:
print(f"{result.message}")
# Test 8: Get debug info
print("\n8. Testing get_debug_info...")
result = await tools.get_debug_info()
test_results.append(("get_debug_info", result.success))
if result.success:
procs = result.data.get("python_processes", [])
print(f" ✓ Found {len(procs)} Python processes")
else:
print(f" ✗ Error: {result.error}")
# Test 9: Format code (check only)
print("\n9. Testing format_code (check mode)...")
result = await tools.format_code(config_file, formatter="black", check_only=True)
test_results.append(("format_code", True)) # Success even if formatting needed
if result.success:
print(f" ✓ Format check completed")
else:
print(f" ⚠ Format issues found (expected): {result.message}")
# Test 10: Execute allowed command
print("\n10. Testing execute_command...")
result = await tools.execute_command("python --version")
test_results.append(("execute_command", result.success))
if result.success:
version = result.data.get("stdout", "").strip()
print(f"{version}")
else:
print(f" ✗ Error: {result.error}")
# Summary
print("\n" + "="*60)
print("📊 TEST SUMMARY")
print("="*60)
passed = sum(1 for _, success in test_results if success)
total = len(test_results)
for name, success in test_results:
status = "✓ PASS" if success else "✗ FAIL"
print(f" {status}: {name}")
print(f"\n Total: {passed}/{total} tests passed")
if passed == total:
print("\n🎉 All tests passed! Server is ready to use.")
return 0
else:
print(f"\n{total - passed} test(s) failed. Check configuration.")
return 1
async def test_tool_call_handler():
"""Test the tool call handler directly."""
print("\n🔧 Testing tool call handler...\n")
class MockServer:
def list_tools(self):
def decorator(func):
return func
return decorator
def call_tool(self):
def decorator(func):
return func
return decorator
tools = PythonProjectTools(MockServer())
# Test a simple tool call
result = await tools.handle_tool_call(
"get_python_env",
{}
)
if result and len(result) > 0:
response = json.loads(result[0].text)
if response.get("success"):
print("✓ Tool call handler working correctly")
return True
else:
print(f"✗ Tool call failed: {response.get('error')}")
return False
else:
print("✗ No response from tool call handler")
return False
async def main():
"""Main test runner."""
print(f"🐍 MCP Python Project Manager - Test Suite")
print(f" Workspace: {config.workspace_root}")
print(f" Debug Mode: {config.debug_mode}")
print(f" Python: {sys.version.split()[0]}\n")
# Run tool tests
tool_test_result = await test_tools()
# Run handler test
handler_result = await test_tool_call_handler()
# Final result
print("\n" + "="*60)
if tool_test_result == 0 and handler_result:
print("✅ ALL TESTS PASSED - Server is ready!")
return 0
else:
print("❌ SOME TESTS FAILED - Please check configuration")
return 1
if __name__ == "__main__":
exit_code = asyncio.run(main())
sys.exit(exit_code)