#!/usr/bin/env node
/**
* MCP 服务器测试运行脚本
* 基于mcp-server-tester的自动化测试执行器
*/
const { spawn } = require('child_process');
const fs = require('fs');
const path = require('path');
// 配置
const CONFIG = {
serverConfig: path.join(__dirname, '../tests/zendao-server-config.json'),
toolTests: path.join(__dirname, '../tests/zendao-tool-tests.yaml'),
evalTests: path.join(__dirname, '../tests/zendao-eval-tests.yaml'),
unifiedTests: path.join(__dirname, '../tests/zendao-unified-tests.yaml'),
reportsDir: path.join(__dirname, '../test-reports'),
};
// 颜色输出
const colors = {
reset: '\x1b[0m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
magenta: '\x1b[35m',
cyan: '\x1b[36m',
white: '\x1b[37m',
};
function colorLog(color, message) {
console.log(`${colors[color]}${message}${colors.reset}`);
}
function log(message) {
console.log(`${colors.white}${message}${colors.reset}`);
}
function success(message) {
console.log(`${colors.green}✅ ${message}${colors.reset}`);
}
function error(message) {
console.log(`${colors.red}❌ ${message}${colors.reset}`);
}
function warning(message) {
console.log(`${colors.yellow}⚠️ ${message}${colors.reset}`);
}
function info(message) {
console.log(`${colors.blue}ℹ️ ${message}${colors.reset}`);
}
// 检查mcp-server-tester是否安装
function checkMcpTester() {
try {
const { execSync } = require('child_process');
execSync('npx mcp-server-tester --version', { stdio: 'ignore' });
return true;
} catch (error) {
return false;
}
}
// 创建报告目录
function ensureReportsDir() {
if (!fs.existsSync(CONFIG.reportsDir)) {
fs.mkdirSync(CONFIG.reportsDir, { recursive: true });
info(`创建报告目录: ${CONFIG.reportsDir}`);
}
}
// 检查配置文件是否存在
function checkConfigFiles() {
const requiredFiles = [
CONFIG.serverConfig,
CONFIG.toolTests,
CONFIG.evalTests,
CONFIG.unifiedTests,
];
const missingFiles = requiredFiles.filter(file => !fs.existsSync(file));
if (missingFiles.length > 0) {
error('以下配置文件不存在:');
missingFiles.forEach(file => error(` - ${file}`));
return false;
}
return true;
}
// 运行MCP测试
async function runMcpTest(testType, options = {}) {
const { debug = false } = options;
let testFile;
let testCommand;
switch (testType) {
case 'tools':
testFile = CONFIG.toolTests;
testCommand = 'tools';
break;
case 'evals':
testFile = CONFIG.evalTests;
testCommand = 'evals';
break;
case 'unified':
testFile = CONFIG.unifiedTests;
testCommand = 'unified';
break;
case 'compliance':
testCommand = 'compliance';
break;
default:
error(`未知的测试类型: ${testType}`);
return false;
}
const args = [
'mcp-server-tester',
testCommand,
];
if (testFile) {
args.push(testFile);
}
args.push('--server-config', CONFIG.serverConfig);
if (debug) {
args.push('--debug');
}
// 生成报告文件名
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const reportFile = path.join(CONFIG.reportsDir, `mcp-test-${testType}-${timestamp}.json`);
// 添加报告输出重定向
const env = {
...process.env,
MCP_TESTER_REPORT: reportFile,
};
return new Promise((resolve, reject) => {
info(`运行MCP ${testType}测试...`);
info(`命令: npx ${args.join(' ')}`);
const process = spawn('npx', args, {
stdio: 'inherit',
env: env,
cwd: path.dirname(CONFIG.serverConfig)
});
process.on('close', (code) => {
if (code === 0) {
success(`MCP ${testType}测试完成`);
if (fs.existsSync(reportFile)) {
info(`报告已保存到: ${reportFile}`);
}
resolve(true);
} else {
error(`MCP ${testType}测试失败 (退出代码: ${code})`);
resolve(false);
}
});
process.on('error', (error) => {
error(`MCP ${testType}测试执行错误: ${error.message}`);
reject(error);
});
});
}
// 主函数
async function main() {
const args = process.argv.slice(2);
colorLog(colors.cyan, '\n🧪 ZenTao MCP 服务器测试运行器');
colorLog(colors.cyan, '====================================\n');
// 检查依赖
if (!checkMcpTester()) {
error('mcp-server-tester 未安装');
info('请运行以下命令安装:');
info('npm install -g @modelcontextprotocol/mcp-server-tester');
info('或者使用 npx: npx @modelcontextprotocol/mcp-server-tester');
process.exit(1);
}
// 检查配置文件
if (!checkConfigFiles()) {
error('请确保所有配置文件都存在');
process.exit(1);
}
// 确保报告目录存在
ensureReportsDir();
// 解析命令行参数
const testType = args[0];
const isDebug = args.includes('--debug');
const isHelp = args.includes('--help') || args.includes('-h');
if (isHelp || !testType) {
showHelp();
return;
}
try {
let success = false;
switch (testType) {
case 'tools':
success = await runMcpTest('tools', { debug: isDebug });
break;
case 'evals':
success = await runMcpTest('evals', { debug: isDebug });
break;
case 'unified':
success = await runMcpTest('unified', { debug: isDebug });
break;
case 'compliance':
success = await runMcpTest('compliance', { debug: isDebug });
break;
case 'all':
info('运行所有测试...\n');
const toolsSuccess = await runMcpTest('tools', { debug: isDebug });
console.log('');
const evalsSuccess = await runMcpTest('evals', { debug: isDebug });
console.log('');
const complianceSuccess = await runMcpTest('compliance', { debug: isDebug });
success = toolsSuccess && evalsSuccess && complianceSuccess;
break;
default:
error(`未知的测试类型: ${testType}`);
showHelp();
return;
}
console.log('');
if (success) {
success('🎉 所有测试执行完成!');
process.exit(0);
} else {
error('💥 测试执行失败!');
process.exit(1);
}
} catch (error) {
error(`测试执行过程中发生错误: ${error.message}`);
process.exit(1);
}
}
// 显示帮助信息
function showHelp() {
console.log(`
${colors.cyan}用法:${colors.reset}
node scripts/run-mcp-tests.js [测试类型] [选项]
${colors.cyan}测试类型:${colors.reset}
tools - 运行工具测试(直接API调用测试)
evals - 运行LLM评估测试(需要ANTHROPIC_API_KEY)
unified - 运行统一测试(包含工具和评估测试)
compliance - 运行MCP规范符合性测试
all - 运行所有测试
${colors.cyan}选项:${colors.reset}
--debug - 启用调试模式,显示详细输出
--help, -h - 显示此帮助信息
${colors.cyan}示例:${colors.reset}
# 运行工具测试
node scripts/run-mcp-tests.js tools
# 运行LLM评估测试(需要设置API密钥)
export ANTHROPIC_API_KEY=your-key
node scripts/run-mcp-tests.js evals
# 运行调试模式的工具测试
node scripts/run-mcp-tests.js tools --debug
# 运行所有测试
node scripts/run-mcp-tests.js all
${colors.cyan}环境变量:${colors.reset}
ANTHROPIC_API_KEY - Claude API密钥(用于evals测试)
ZENDTAO_BASE_URL - 禅道服务器URL
ZENDTAO_TOKEN - 禅道访问令牌
${colors.cyan}测试报告:${colors.reset}
测试报告将保存在 ${CONFIG.reportsDir} 目录中
`);
}
// 运行主函数
if (require.main === module) {
main().catch(error => {
console.error(`未处理的错误: ${error}`);
process.exit(1);
});
}