أنظمة MCP الإنتاجية
الاختبار وأفضل الممارسات
5 دقيقة للقراءة
هناك صنف من الأخطاء هنا لا تراه الاختبارات المعتادة: قد يكون خادمك صحيحاً تماماً وغير قابل للاستخدام في الوقت نفسه، لأن النموذج لا يستدعي الأداة أصلاً أو يستدعيها بمعطيات خاطئة. كل مستوى اختبار أدناه يلتقط إخفاقاً مختلفاً، وآخرها هو الذي يتخطاه الناس.
فئات الاختبار
ثلاثة مستويات، ثلاثة إخفاقات مختلفة
سريع
الوحدة
يختبردالة واحدة بمعزل عن غيرها
يلتقطمنطقاً خاطئاً وتحققاً رديئاً
السرعةأجزاء من الثانية، شغّله عند كل حفظ
يفوتهكل ما يتعلق بترابط الأجزاء
المزايا
- رخيص بما يكفي لتشغيله باستمرار
- الإخفاق يشير إلى دالة واحدة بعينها
العيوب
- قد يجتاز الخادم كل اختبارات الوحدة ثم لا يقلع أصلاً
على مستوى البروتوكول
التكامل
يختبرطلبات حقيقية عبر الموزّع الحقيقي
يلتقطتوصيلاً مكسوراً ومخططات ومظاريف مشوّهة
السرعةثوانٍ، شغّله في CI
يفوتههل سيختار النموذج هذه الأداة أصلاً
المزايا
- يتحقق من أن tools/list و tools/call تعملان فعلاً
- يلتقط أخطاء التسجيل التي تعجز عنها اختبارات الوحدة
العيوب
- يحتاج بيانات تجريبية وبدائل للخدمات الخارجية ليبقى سريعاً
الأكثر تخطياً
الاختبار الشامل بنموذج حقيقي
يختبرمضيف حقيقي ونموذج حقيقي وطلب حقيقي
يلتقطأوصافاً يسيء النموذج قراءتها أو يتجاهلها
السرعةبطيء وغير حتمي
يفوتهالقليل، لكنه لن يخبرك بالسبب
المزايا
- المستوى الوحيد الذي يختبر أوصاف أدواتك إطلاقاً
- يكشف الأدوات التي لا تُختار أبداً، وهو ما يعجز عنه أي اختبار آخر
العيوب
- غير حتمي، فتعامل مع إخفاقاته كمؤشر لا كبوابة
- يكلّف نداء API حقيقياً في كل تشغيل
العمود الثالث هو الأهم والأقل أتمتة. فأوصاف أدواتك جزء من واجهتك عملياً، واختبارات الوحدة لا تقرؤها. وقائمة قصيرة من الطلبات الحقيقية تُنفَّذ يدوياً قبل كل إصدار تلتقط مشكلات فعلية أكثر مما تلتقطه عشرات اختبارات الوحدة الإضافية: هل يقصد النموذج الأداة الصحيحة، بمعطيات معقولة، دون أن تُذكر له باسمها؟
اختبار وحدة الأدوات
import pytest
from unittest.mock import AsyncMock, patch
from server import WeatherTool
class TestWeatherTool:
def test_get_definition(self):
tool = WeatherTool()
definition = tool.get_tool_definition()
assert definition["name"] == "get_weather"
assert "city" in definition["inputSchema"]["properties"]
def test_validate_valid_input(self):
tool = WeatherTool()
assert tool.validate({"city": "London"}) == True
def test_validate_empty_city(self):
tool = WeatherTool()
with pytest.raises(ValueError, match="المدينة مطلوبة"):
tool.validate({"city": ""})
@pytest.mark.asyncio
async def test_execute(self):
tool = WeatherTool()
result = await tool.execute({"city": "London"})
assert "temperature" in result
assert "condition" in result
اختبار التكامل
import pytest
from httpx import AsyncClient
from server import app
@pytest.fixture
async def client():
async with AsyncClient(app=app, base_url="http://test") as ac:
yield ac
@pytest.mark.asyncio
async def test_mcp_endpoint(client):
response = await client.post("/mcp", json={
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
})
assert response.status_code == 200
data = response.json()
assert "tools" in data
@pytest.mark.asyncio
async def test_tool_call(client):
response = await client.post("/mcp", json={
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {"city": "Tokyo"}
}
})
assert response.status_code == 200
assert response.json()["result"]
محاكاة الخدمات الخارجية
@pytest.mark.asyncio
async def test_weather_api_failure():
with patch("server.fetch_weather", new_callable=AsyncMock) as mock:
mock.side_effect = Exception("API غير متاح")
tool = WeatherTool()
with pytest.raises(McpError) as exc:
await tool.execute({"city": "London"})
assert "غير متاح" in str(exc.value)
ملخص أفضل الممارسات
| الممارسة | الفائدة |
|---|---|
| استخدم متغيرات البيئة | الأمان، المرونة |
| نفذ فحوصات الصحة | مراقبة الموثوقية |
| أضف مهلات الطلب | منع التعليق |
| سجّل بيانات منظمة | تصحيح سهل |
| نسّخ API الخاص بك | التوافق العكسي |
| وثّق الأدوات بوضوح | استخدام AI أفضل |
| اختبر الحالات الحدية | معالجة قوية |
قائمة مراجعة الإنتاج
- جميع الأسرار في متغيرات البيئة
- نقطة نهاية فحص الصحة منفذة
- مقاييس Prometheus مكشوفة
- التسجيل المنظم مكوّن
- تحديد المعدل مُمَكَّن
- CORS مكوّن بشكل صحيح
- SSL/TLS مُمَكَّن
- معالجة الأخطاء شاملة
- الاختبارات تمر في CI/CD
التالي: المشروع النهائي — جمع الوحدات الخمس في خادم واحد تشغّله فعلاً. :::
هل كان هذا الدرس مفيدًا؟
سجّل الدخول للتقييم