51 lines
1.7 KiB
Python
51 lines
1.7 KiB
Python
# requires: mcp, pydantic, pytest, anyio
|
|
import json
|
|
|
|
import anyio
|
|
import pytest
|
|
|
|
from mcp import Client
|
|
|
|
from kb_server import TICKETS, mcp
|
|
|
|
|
|
@pytest.fixture
|
|
def anyio_backend():
|
|
return "asyncio"
|
|
|
|
|
|
async def _session():
|
|
async with Client(mcp) as c: # 测试时直接传入服务对象,进程内通信
|
|
tools = {t.name: t for t in (await c.list_tools()).tools}
|
|
assert set(tools) == {"search_docs", "create_ticket"}
|
|
assert "request_id" in json.dumps(tools["create_ticket"].input_schema)
|
|
|
|
r = await c.call_tool("search_docs", {"query": "VPN 失败"})
|
|
assert not r.is_error and "vpn" in json.dumps(r.structured_content, ensure_ascii=False)
|
|
|
|
args = {"ticket": {"title": "VPN 无法连接", "category": "it", "request_id": "req-1"}}
|
|
first = await c.call_tool("create_ticket", args)
|
|
second = await c.call_tool("create_ticket", args)
|
|
assert first.structured_content == second.structured_content and len(TICKETS) == 1
|
|
|
|
bad = await c.call_tool("create_ticket", {"ticket": {"title": "x", "category": "other", "request_id": "r"}})
|
|
assert bad.is_error # 参数校验失败以错误结果返回给客户端
|
|
|
|
res = await c.read_resource("kb://docs/expense")
|
|
assert "600" in res.contents[0].text
|
|
|
|
p = await c.get_prompt("answer_with_citation", {"question": "住宿标准"})
|
|
assert "search_docs" in p.messages[0].content.text
|
|
return r
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_kb_server():
|
|
await _session()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
r = anyio.run(_session)
|
|
print("search_docs 结构化结果:", r.structured_content)
|
|
print("工单:", TICKETS)
|