Skip to main content
Glama
leeguooooo
by leeguooooo
TESTING_GUIDE.md12 kB
# 测试指南 - UID 和 Account ID 修复验证 ## 测试目标 验证两个关键修复: 1. ✅ **Account ID 修复**:返回真实的账户 ID(如 `leeguoo_qq`)而不是邮箱地址 2. ✅ **UID 支持**:所有操作都支持 UID 和序列号,自动回退 ## 测试环境准备 ### 1. 检查账户配置 ```bash cat accounts.json ``` 应该看到类似: ```json { "accounts": { "env_163": { "email": "leeguoo@163.com", ... }, "leeguoo_qq": { "email": "leeguoo@qq.com", ... } } } ``` **关键点**:账户 ID 是 `env_163` 和 `leeguoo_qq`,不是邮箱地址。 ### 2. 启动 MCP 服务 ```bash # 如果使用 npx npx -y @modelcontextprotocol/inspector python -m src.main # 或者直接运行 python -m src.main ``` ## 测试场景 ### 场景 1:验证 list_emails 返回正确的 account_id **测试步骤**: ```javascript // 1. 列出邮件(使用特定账户) { "tool": "list_emails", "arguments": { "limit": 5, "account_id": "leeguoo_qq" // 使用真实的账户 ID } } ``` **预期结果**: ```json { "emails": [ { "id": "1", "subject": "测试邮件", "account": "leeguoo@qq.com", "account_id": "leeguoo_qq" // ✅ 应该是账户 ID,不是邮箱 } ], "account_id": "leeguoo_qq" // ✅ 列表级别也应该有 } ``` **验证点**: - ✅ `account_id` 字段存在 - ✅ `account_id` = `"leeguoo_qq"` (不是 `"leeguoo@qq.com"`) --- ### 场景 2:验证 search_emails 返回正确的 account_id **测试步骤**: ```javascript // 2. 搜索邮件 { "tool": "search_emails", "arguments": { "query": "招聘", "account_id": "env_163" } } ``` **预期结果**: ```json { "success": true, "emails": [ { "id": "1186", // 这是 UID "subject": "地上铁招聘", "account": "leeguoo@163.com", "account_id": "env_163" // ✅ 真实账户 ID } ], "account_id": "env_163" } ``` --- ### 场景 3:验证 get_email_detail 使用 account_id 能正确路由 **测试步骤**: ```javascript // 3. 从搜索结果获取详情(使用返回的 account_id) // 假设搜索返回了 {"id": "1186", "account_id": "env_163"} { "tool": "get_email_detail", "arguments": { "email_id": "1186", // UID "account_id": "env_163" // 使用返回的 account_id } } ``` **预期结果**: ```json { "id": "1186", "uid": "1186", // ✅ 使用了 UID "subject": "地上铁招聘", "body": "...", "account": "leeguoo@163.com", "account_id": "env_163" // ✅ 返回真实 ID } ``` **关键验证**: - ✅ 能成功获取邮件(不报错 "Email not found") - ✅ 返回的是正确的邮件内容 - ✅ `account_id` 是 `"env_163"` --- ### 场景 4:验证 UID 回退机制 **测试 4A:使用 UID(来自 search)** ```javascript // 先搜索 { "tool": "search_emails", "arguments": { "query": "test", "limit": 1 } } // 假设返回 {"id": "1186", "account_id": "env_163"} // 然后标记为已读 { "tool": "mark_email_read", "arguments": { "email_id": "1186", // UID "account_id": "env_163" } } ``` **预期**: - ✅ 成功标记 - ✅ 日志显示 "Successfully used UID"(如果开启 DEBUG) **测试 4B:使用序列号(来自 list)** ```javascript // 先列表 { "tool": "list_emails", "arguments": { "limit": 1, "account_id": "env_163" } } // 假设返回 {"id": "1", "account_id": "env_163"} // 然后标记为已读 { "tool": "mark_email_read", "arguments": { "email_id": "1", // 序列号 "account_id": "env_163" } } ``` **预期**: - ✅ 成功标记(回退到序列号) - ✅ 日志可能显示 "UID store failed, trying sequence number" --- ### 场景 5:验证批量操作 ```javascript // 5. 批量标记为已读 { "tool": "batch_mark_read", "arguments": { "email_ids": ["1186", "1187", "1188"], // UIDs from search "account_id": "env_163" } } ``` **预期结果**: ```json { "success": true, "message": "Marked 3/3 emails as read", "account": "leeguoo@163.com", "account_id": "env_163", // ✅ 返回真实 ID "failed_ids": [] // ✅ 应该为空(全部成功) } ``` --- ## 错误场景测试 ### 测试错误的 account_id ```javascript { "tool": "get_email_detail", "arguments": { "email_id": "123", "account_id": "nonexistent_account" } } ``` **预期**: - ❌ 返回错误:"No email account configured" ### 测试错误的邮箱地址作为 account_id(验证修复前的问题) ```javascript { "tool": "get_email_detail", "arguments": { "email_id": "123", "account_id": "leeguoo@qq.com" // ❌ 应该用 "leeguoo_qq" } } ``` **修复前**:会回退到默认账户,取到错误的邮件 **修复后**:应该返回错误或回退到默认账户(取决于实现) --- ## 使用 Python 脚本测试 创建测试脚本 `test_account_id_fix.py`: ```python #!/usr/bin/env python3 """测试 account_id 修复""" import sys sys.path.insert(0, 'src') from legacy_operations import ( fetch_emails, get_email_detail, mark_email_read ) from operations.search_operations import EmailSearchOperations from account_manager import AccountManager import json def test_list_emails(): """测试 list_emails 返回正确的 account_id""" print("=" * 60) print("测试 1: list_emails 返回 account_id") print("=" * 60) result = fetch_emails(limit=2, account_id="leeguoo_qq") if 'error' in result: print(f"❌ 错误: {result['error']}") return False print(f"✅ 列表级 account_id: {result.get('account_id')}") if result.get('emails'): first_email = result['emails'][0] print(f"✅ 邮件级 account_id: {first_email.get('account_id')}") print(f" 邮件 ID: {first_email.get('id')}") print(f" 账户邮箱: {first_email.get('account')}") # 验证 if first_email.get('account_id') == 'leeguoo_qq': print("✅ PASS: account_id 正确") return True, first_email.get('id') else: print(f"❌ FAIL: account_id 应该是 'leeguoo_qq',实际是 '{first_email.get('account_id')}'") return False, None return False, None def test_get_email_detail(email_id, account_id): """测试 get_email_detail 能正确路由""" print("\n" + "=" * 60) print(f"测试 2: get_email_detail 路由到正确账户") print(f" email_id: {email_id}") print(f" account_id: {account_id}") print("=" * 60) result = get_email_detail(email_id, account_id=account_id) if 'error' in result: print(f"❌ 错误: {result['error']}") return False print(f"✅ 成功获取邮件") print(f" 主题: {result.get('subject', 'N/A')[:50]}") print(f" account_id: {result.get('account_id')}") print(f" uid: {result.get('uid')}") if result.get('account_id') == account_id: print("✅ PASS: account_id 正确") return True else: print(f"❌ FAIL: account_id 不匹配") return False def test_search_emails(): """测试搜索返回正确的 account_id""" print("\n" + "=" * 60) print("测试 3: search_emails 返回 account_id") print("=" * 60) account_mgr = AccountManager() account = account_mgr.get_account("env_163") if not account: print("❌ 找不到账户 env_163") return False, None from connection_manager import ConnectionManager conn_mgr = ConnectionManager(account) searcher = EmailSearchOperations(conn_mgr) result = searcher.search_emails( query="", # 搜索所有 limit=2, account_id="env_163" ) if not result.get('success'): print(f"❌ 搜索失败: {result}") return False, None print(f"✅ 搜索到 {len(result.get('emails', []))} 封邮件") if result.get('emails'): first = result['emails'][0] print(f" 第一封邮件:") print(f" - ID: {first.get('id')}") print(f" - account_id: {first.get('account_id')}") if first.get('account_id') == 'env_163': print("✅ PASS: account_id 正确") return True, first.get('id') else: print(f"❌ FAIL: account_id 应该是 'env_163'") return False, None return False, None if __name__ == '__main__': print("\n" + "🧪 " * 20) print("Account ID 修复测试") print("🧪 " * 20 + "\n") # 测试 1: list_emails success1, email_id = test_list_emails() # 测试 2: get_email_detail(如果测试1成功) success2 = False if success1 and email_id: success2 = test_email_detail(email_id, "leeguoo_qq") # 测试 3: search_emails success3, search_id = test_search_emails() # 总结 print("\n" + "=" * 60) print("测试总结") print("=" * 60) print(f"list_emails: {'✅ PASS' if success1 else '❌ FAIL'}") print(f"get_email_detail: {'✅ PASS' if success2 else '❌ FAIL'}") print(f"search_emails: {'✅ PASS' if success3 else '❌ FAIL'}") if success1 and success2 and success3: print("\n🎉 所有测试通过!") sys.exit(0) else: print("\n❌ 部分测试失败") sys.exit(1) ``` 运行测试: ```bash python test_account_id_fix.py ``` --- ## 快速验证命令 ### 方法 1:使用 MCP Inspector ```bash # 启动 inspector npx -y @modelcontextprotocol/inspector python -m src.main # 在 inspector 中调用工具,观察返回的 account_id ``` ### 方法 2:使用 Python REPL ```python python3 >>> import sys >>> sys.path.insert(0, 'src') >>> from legacy_operations import fetch_emails >>> >>> # 测试 >>> result = fetch_emails(limit=1, account_id="leeguoo_qq") >>> print(result.get('account_id')) # 应该输出 "leeguoo_qq" >>> >>> # 测试邮件级别 >>> if result.get('emails'): ... print(result['emails'][0].get('account_id')) # 也应该是 "leeguoo_qq" ``` ### 方法 3:检查日志 开启 DEBUG 日志: ```bash # 设置环境变量 export LOG_LEVEL=DEBUG # 运行服务 python -m src.main ``` 查找日志中的关键信息: ``` DEBUG - Successfully fetched email using UID 1186 DEBUG - UID store failed for 999, trying sequence number ``` --- ## 预期的修复效果 ### 修复前 ❌ ```json { "id": "1186", "account_id": "leeguoo@qq.com" // ❌ 邮箱地址 } // 再次调用时 get_email_detail("1186", account_id="leeguoo@qq.com") // → AccountManager.get_account("leeguoo@qq.com") → None // → 回退到默认账户 → 错误的邮件或找不到 ``` ### 修复后 ✅ ```json { "id": "1186", "account_id": "leeguoo_qq" // ✅ 真实账户 ID } // 再次调用时 get_email_detail("1186", account_id="leeguoo_qq") // → AccountManager.get_account("leeguoo_qq") → Success! // → 正确的账户 → 正确的邮件 ``` --- ## 故障排查 ### 问题:仍然返回邮箱地址 **检查**: ```bash # 1. 确认代码已更新 grep "self.account_id" src/connection_manager.py # 2. 确认没有缓存的 .pyc 文件 find . -name "*.pyc" -delete find . -name "__pycache__" -type d -delete # 3. 重启服务 ``` ### 问题:account_id 为 None **原因**:环境变量账户没有 ID **解决**:为环境变量账户添加到 accounts.json,或者修改回退逻辑: ```python # 在 ConnectionManager.__init__ 中 self.account_id = account_config.get('id') or f"env_{self.email.split('@')[0]}" ``` --- ## 成功标准 ✅ 所有测试场景通过 ✅ `account_id` 返回的是账户键名(如 `"leeguoo_qq"`) ✅ 使用返回的 `account_id` 能正确路由到对应账户 ✅ UID 和序列号都能工作 ✅ 没有 "Email not found" 错误(在正确使用时) --- 需要帮助创建测试脚本或运行特定测试吗?

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/leeguooooo/email-mcp-service'

If you have feedback or need assistance with the MCP directory API, please join our Discord server