Skip to main content
Glama
run_tests.py8.55 kB
#!/usr/bin/env python3 """ 测试运行器 支持运行不同类型的测试:本地测试、npm测试、集成测试 """ import sys import os import unittest import argparse from pathlib import Path from typing import List, Optional import time # 添加项目根目录到Python路径 PROJECT_ROOT = Path(__file__).parent.parent sys.path.insert(0, str(PROJECT_ROOT)) sys.path.insert(0, str(PROJECT_ROOT / 'python')) # 添加测试工具路径 sys.path.insert(0, str(Path(__file__).parent / 'utils')) from test_helpers import TestReporter class TestRunner: """测试运行器""" def __init__(self): self.project_root = PROJECT_ROOT self.tests_dir = Path(__file__).parent self.reporter = TestReporter() def discover_tests(self, test_type: str = "all") -> List[str]: """发现测试文件""" test_files = [] if test_type in ["all", "local"]: local_tests = list((self.tests_dir / "local").glob("test_*.py")) test_files.extend([str(f) for f in local_tests]) if test_type in ["all", "npm"]: npm_tests = list((self.tests_dir / "npm").glob("test_*.py")) test_files.extend([str(f) for f in npm_tests]) if test_type in ["all", "integration"]: integration_tests = list((self.tests_dir / "integration").glob("test_*.py")) test_files.extend([str(f) for f in integration_tests]) return test_files def run_test_file(self, test_file: str, verbose: bool = False) -> unittest.TestResult: """运行单个测试文件""" # 动态导入测试模块 test_path = Path(test_file) module_name = test_path.stem # 添加测试文件所在目录到路径 sys.path.insert(0, str(test_path.parent)) try: # 导入测试模块 spec = __import__(module_name) # 创建测试套件 loader = unittest.TestLoader() suite = loader.loadTestsFromModule(spec) # 运行测试 runner = unittest.TextTestRunner( verbosity=2 if verbose else 1, stream=sys.stdout, buffer=True ) result = runner.run(suite) return result except Exception as e: print(f"❌ 运行测试文件 {test_file} 失败: {e}") # 创建一个失败的结果 result = unittest.TestResult() result.errors.append((test_file, str(e))) return result finally: # 清理路径 if str(test_path.parent) in sys.path: sys.path.remove(str(test_path.parent)) def run_tests(self, test_type: str = "all", verbose: bool = False, specific_test: Optional[str] = None) -> bool: """运行测试""" print(f"🚀 开始运行 {test_type} 测试...") print(f"📁 项目根目录: {self.project_root}") print(f"🧪 测试目录: {self.tests_dir}") print("=" * 60) start_time = time.time() if specific_test: # 运行特定测试文件 test_files = [specific_test] if Path(specific_test).exists() else [] if not test_files: print(f"❌ 测试文件不存在: {specific_test}") return False else: # 发现测试文件 test_files = self.discover_tests(test_type) if not test_files: print(f"⚠️ 没有找到 {test_type} 类型的测试文件") return True print(f"📋 发现 {len(test_files)} 个测试文件:") for test_file in test_files: print(f" - {Path(test_file).name}") print() # 运行所有测试 total_tests = 0 total_failures = 0 total_errors = 0 for test_file in test_files: print(f"🧪 运行测试: {Path(test_file).name}") print("-" * 40) result = self.run_test_file(test_file, verbose) # 统计结果 tests_run = result.testsRun failures = len(result.failures) errors = len(result.errors) total_tests += tests_run total_failures += failures total_errors += errors # 记录结果 if failures == 0 and errors == 0: self.reporter.add_result(Path(test_file).name, "PASS", f"{tests_run} 个测试通过") print(f"✅ {Path(test_file).name}: {tests_run} 个测试通过") else: error_msg = f"{failures} 个失败, {errors} 个错误" self.reporter.add_result(Path(test_file).name, "FAIL", error_msg) print(f"❌ {Path(test_file).name}: {error_msg}") print() # 生成总结报告 end_time = time.time() duration = end_time - start_time print("=" * 60) print("📊 测试总结") print("=" * 60) print(f"总测试数: {total_tests}") print(f"通过: {total_tests - total_failures - total_errors}") print(f"失败: {total_failures}") print(f"错误: {total_errors}") print(f"耗时: {duration:.2f} 秒") # 保存详细报告 report_file = self.tests_dir / f"test_report_{test_type}_{int(time.time())}.txt" self.reporter.save_report(report_file) print(f"📄 详细报告已保存到: {report_file}") # 返回是否所有测试都通过 success = total_failures == 0 and total_errors == 0 if success: print("🎉 所有测试通过!") else: print("💥 有测试失败,请检查上面的错误信息") return success def run_pre_commit_tests(self) -> bool: """运行提交前测试(本地测试 + 回归测试)""" print("🔍 运行提交前测试...") # 运行本地测试 local_success = self.run_tests("local", verbose=False) if not local_success: print("❌ 本地测试失败,请修复后再提交") return False print("✅ 提交前测试通过") return True def run_pre_publish_tests(self) -> bool: """运行发布前测试(所有测试)""" print("📦 运行发布前测试...") # 运行所有测试 all_success = self.run_tests("all", verbose=True) if not all_success: print("❌ 发布前测试失败,请修复后再发布") return False print("✅ 发布前测试通过") return True def main(): """主函数""" parser = argparse.ArgumentParser(description="Remote Terminal MCP 测试运行器") parser.add_argument( "test_type", nargs="?", default="all", choices=["all", "local", "npm", "integration"], help="要运行的测试类型 (默认: all)" ) parser.add_argument( "-v", "--verbose", action="store_true", help="详细输出" ) parser.add_argument( "-f", "--file", help="运行特定的测试文件" ) parser.add_argument( "--pre-commit", action="store_true", help="运行提交前测试" ) parser.add_argument( "--pre-publish", action="store_true", help="运行发布前测试" ) args = parser.parse_args() runner = TestRunner() try: if args.pre_commit: success = runner.run_pre_commit_tests() elif args.pre_publish: success = runner.run_pre_publish_tests() else: success = runner.run_tests( test_type=args.test_type, verbose=args.verbose, specific_test=args.file ) sys.exit(0 if success else 1) except KeyboardInterrupt: print("\n⚠️ 测试被用户中断") sys.exit(1) except Exception as e: print(f"💥 测试运行器出错: {e}") sys.exit(1) if __name__ == "__main__": main()

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/maricoxu/remote-terminal-mcp'

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