
PostgreSQL MCP 服务器测试体系实战指南单元测试、集成测试与测试基础设施全解析【免费下载链接】klavisKlavis AI: MCP integration platforms that let AI agents use tools reliably at any scale项目地址: https://gitcode.com/GitHub_Trending/kl/klavisKlavis 仓库中的 mcp_servers/postgres 是一个基于 Model Context ProtocolMCP的 PostgreSQL 调优与分析服务器Postgres MCP Pro而 mcp_servers/postgres/tests/README.md 则是其官方测试说明文档。本文以该文档为主体骨架结合仓库内实际的测试源码、被测实现与测试基础设施完整讲解如何运行这套测试、每个测试文件覆盖了什么行为、以及测试背后的 Docker HypoPG 支撑机制帮助你快速掌握并扩展这套面向数据库 MCP 服务器的质量保障体系。一、测试体系概览从文档看整体布局tests/README.md开篇即说明该目录存放的是 PostgreSQL MCP 包的测试。从仓库实际目录结构看测试被清晰地划分为两大层级单元测试mcp_servers/postgres/tests/unit/针对单个组件和函数不依赖真实数据库主要使用unittest.mock的AsyncMock/MagicMock模拟连接、游标与连接池。sql/子目录密码脱敏、连接池、SQL 驱动、安全 SQL 校验database_health/子目录数据库健康检查工具与序列健康计算explain/子目录EXPLAIN 计划生成与服务器工具含真实数据库集成测试index/子目录索引调优的 DTADatabase Tuning Advisor计算top_queries/子目录慢查询统计计算根级文件test_access_mode.py访问模式、test_transport.py传输层。集成测试mcp_servers/postgres/tests/integration/依赖真实 PostgreSQL 实例例如dta/test_dta_calc_integration.py与test_top_queries_integration.py用于验证索引调优与慢查询分析在真实数据库上的行为。文档本身虽简短但它点明了测试的三个核心入口与三类关键被测对象下文将逐一展开并结合源码把每个点讲透。二、运行测试三种命令与更多实用变体2.1 文档给出的三种标准运行方式在mcp_servers/postgres目录下使用uv作为包管理工具即可运行全部测试uv run pytest只运行某一个测试文件例如密码脱敏测试注意文档中的tests/unit/test_obfuscate_password.py在实际仓库中位于tests/unit/sql/子目录下应以实际路径为准uv run pytest tests/unit/sql/test_obfuscate_password.py只运行某个测试类中的单个用例例如连接池的成功连接测试uv run pytest tests/unit/sql/test_db_conn_pool.py::test_pool_connect_success::语法是 pytest 的标准节点选择写法文件路径::测试函数名可以精确到任意一个用例适合在调试时快速复现单个失败。2.2 面向调试与集成的更多运行方式除文档给出的命令外结合 pytest 特性与仓库配置还可以这样用# 只跑单元测试不依赖 Docker 与真实数据库 uv run pytest tests/unit -v # 只跑集成测试需要 Docker 可用 uv run pytest tests/integration -v # 精确运行带参数的用例conftest 中按 Postgres 版本参数化 uv run pytest tests/unit/explain/test_explain_plan_real_db.py # 显示详细输出与 print 内容 uv run pytest -v -s # 只收集不执行快速核对用例清单 uv run pytest --collect-only2.3 测试运行的前提条件单元测试绝大多数用例通过 mock 隔离数据库依赖运行前仅需安装项目依赖与dev依赖组pytest、pytest-asyncio 等无需真实数据库。集成测试需要本地 Docker 可用。仓库的conftest.py与tests/utils.py会在没有 Docker 或镜像构建失败时调用pytest.skip()优雅跳过而不是直接报错中断——这一点在 tests/utils.py 中有多处体现。三、单元测试核心模块逐层解析tests/README.md列出的三个单元测试文件对应 src/postgres_mcp/sql/sql_driver.py 中的核心组件下面逐一结合源码讲解。3.1 密码脱敏test_obfuscate_password.py被测函数obfuscate_password源码见 sql_driver.py用于把连接信息中的密码替换为****防止错误消息或日志泄露凭据。它的实现依次处理四类场景尝试按标准 URL 解析urlparse命中则替换netloc中的密码用正则匹配postgres://user:passwordhost:port/db形态的 URL 片段匹配passwordxxx键值对无引号匹配 DSN 单引号与双引号格式的password .../password ...。对应测试文件 test_obfuscate_password.py 覆盖了 8 组行为测试函数验证内容test_obfuscate_none_or_empty空字符串原样返回None返回Nonetest_obfuscate_postgresql_url标准 URL、含$等特殊字符的密码、带?sslmoderequire查询参数均被脱敏且保留其余部分test_obfuscate_in_error_message错误消息中内嵌的连接串也被脱敏topsecret变为****test_obfuscate_connection_paramshost... passwordsecret123键值对格式Python 代码片段中的单引号密码test_obfuscate_multiple_passwords同一文本中多个连接串的密码全部脱敏test_obfuscate_no_sensitive_data无敏感数据的普通文本原样不变test_obfuscate_dsn_format单引号与双引号两种 DSN 格式这一模块的意义在于DbConnPool.pool_connect在连接失败时会抛出ValueError(fConnection attempt failed: {obfuscate_password(str(e))})确保传给上层 MCP 客户端的错误信息不会包含数据库密码。3.2 连接池test_db_conn_pool.py被测类DbConnPoolsql_driver.py基于 psycopg 的AsyncConnectionPool封装了异步连接池管理关键行为包括池配置固定为min_size1, max_size5且openFalse延迟打开pool_connect()具备已有效则复用的短路逻辑避免重复建池建池后执行SELECT 1探活成功才标记_is_valid True失败时清理池并抛错错误信息经密码脱敏close()对关闭异常做了兜底处理保证池状态最终重置。test_db_conn_pool.py 通过自定义的AsyncContextManagerMock模拟异步上下文管理器覆盖了 8 个场景test_pool_connect_success正常建池成功test_pool_connect_with_retry/test_pool_connect_all_retries_fail首次失败后重试、全部失败时标记池无效test_close_pool/test_close_handles_errors正常关闭与异常关闭均重置_is_valid与pooltest_pool_connect_initialized/test_pool_connect_not_initialized已初始化时复用现有池、未初始化时才真正连接test_connection_url_propertyconnection_url属性的读写。3.3 SQL 驱动test_sql_driver.py被测类SqlDriversql_driver.py是连接与 SQL 执行之间的适配层核心方法是execute_query(query, params, force_readonly)与内部_execute_with_connection。从实现看它有两条值得注意的执行路径连接池路径从池中取连接执行直连路径直接使用传入的连接。事务处理采用显式控制force_readonlyTrue时执行BEGIN TRANSACTION READ ONLY并以ROLLBACK结束只读事务天然不可提交否则以COMMIT结束。cursor.description is None表示无结果集如 DDL此时只读模式下同样回滚。异常时若事务仍活跃则调用connection.rollback()兜底。test_sql_driver.py 覆盖了 10 个场景只读事务与可写事务的正确BEGIN/COMMIT/ROLLBACK序列查询执行失败时的异常传递无结果集查询返回None带参数查询%s占位符与参数列表正确透传从池中取连接执行并正确组装RowResult连接错误时池被标记为无效并记录_last_error通过engine_url而非连接对象初始化时自动构建DbConnPoolis_poolTrue。RowResult是一个仅含cells: Dict[str, Any]的简单数据类测试验证了结果行被转换为RowResult且字段可经result[0].cells[id]访问。3.4 安全 SQLtest_safe_sql.py文档未列出的重要补充虽然tests/README.md只列出三个文件但仓库中tests/unit/sql/下还有一个体量很大的 test_safe_sql.py对应SafeSqlDriver这一安全执行层。它与服务器restricted只读模式直接相关建议一并了解放行SELECT含 JOIN、子查询、UNION、算术表达式、SHOW、EXPLAIN不带ANALYZE、只读系统视图查询pg_stat_statements、pg_indexes、pg_stats、hypopg_*模拟索引函数、CREATE EXTENSION IF NOT EXISTS hypopg、日期/网络/权限相关函数等拦截UPDATE/DELETE/DROP/CREATE系列、SET、SELECT INTO、SELECT ... FOR UPDATE/FOR SHARE、BEGIN、COMMIT、EXPLAIN ANALYZE、含注释注入的多语句SELECT * FROM users; DROP TABLE users;、危险函数pg_sleep、pg_read_file、lo_import以及语法非法语句。该测试还验证了SafeSqlDriver在执行前会为查询加上/* crystaldba */注释前缀并以force_readonlyTrue转发给底层SqlDriver——这是服务器在读写连接之上强行施加只读保护的实现细节。四、更广泛的单元测试覆盖除 SQL 核心模块外tests/unit/还覆盖了 Postgres MCP Pro 的性能分析与健康检查功能database_health/test_database_health_tool.py与test_sequence_health_calc.py验证 database_health 模块中缓冲命中率、连接健康、约束、索引健康、序列上限、vacuum 与复制延迟等检查逻辑explain/test_explain_plan.py验证 EXPLAIN 计划生成test_explain_plan_real_db.py与test_server_integration.py需要真实数据库test_server.py验证 MCP 服务器层行为index/test_dta_calc.py验证 index/dta_calc.py 中基于 Microsoft SQL Server Anytime 算法的索引候选生成与贪心搜索逻辑top_queries/test_top_queries_calc.py验证基于pg_stat_statements的慢查询统计计算根级test_access_mode.py验证 unrestricted/restricted 两种访问模式的切换test_transport.py验证 stdio 与 SSE 两种 MCP 传输方式。这些测试共同构成了确定性工具 经典优化算法的质量防线健康检查结果可重复索引推荐来自有依据的搜索而非 LLM 猜测。五、集成测试真实数据库上的端到端验证集成测试目录mcp_servers/postgres/tests/integration/包含dta/test_dta_calc_integration.py与test_top_queries_integration.py它们验证在真实 PostgreSQL 实例上索引调优建议DTA能否真正产生合理结果基于pg_stat_statements的 Top 查询分析能否正确识别慢查询。要运行这些测试需要本地 Docker。基础设施由 tests/conftest.py 提供pytest.fixture(scopeclass, params[postgres:12, postgres:15, postgres:16]) def test_postgres_connection_string(request): yield from create_postgres_container(request.param)该 fixture 对postgres:12、postgres:15、postgres:16三个版本做参数化为每个用例启动一个独立的 PostgreSQL 容器。此外conftest.py还提供event_loop_policy会话级自定义事件循环策略保证异步测试的清理行为稳定reset_pg_version_cacheautouse每个测试前重置 Postgres 版本缓存避免版本判断结果在用例间串扰。六、测试基础设施Docker 容器与 HypoPG6.1 容器生命周期管理tests/utils.py 中的create_postgres_container是集成测试的引擎关键流程如下探测 Docker 是否可用不可用则pytest.skip按版本构建/复用自定义镜像postgres-hypopg:version基于 tests/Dockerfile.postgres-hypopg启动容器并让 Docker 随机分配宿主机端口ports{5432/tcp: (127.0.0.1, 0)}避免端口冲突以-c shared_preload_librariespg_stat_statements、-c pg_stat_statements.trackall启动 Postgres确保pg_stat_statements生效轮询pg_isready最多 60 秒等待数据库就绪产出连接串postgresql://postgres:test_passwordlocalhost:port/test_db供测试使用finally中停止并删除容器container.remove(vTrue)保证环境干净。6.2 带 HypoPG 的测试镜像tests/Dockerfile.postgres-hypopg 以官方postgres:version为基础完成三件事安装build-essential、git、postgresql-server-dev-*等编译依赖从源码编译安装 HypoPG 扩展make make install写入初始化脚本/docker-entrypoint-initdb.d/00-create-extensions.sql在首次启动时自动执行CREATE EXTENSION IF NOT EXISTS pg_stat_statements; CREATE EXTENSION IF NOT EXISTS hypopg;这解释了 README 中索引调优依赖pg_stat_statements与hypopg的说法前者提供查询执行统计以定位慢查询后者让优化器虚拟地评估添加索引后的执行计划从而在不动真实数据的前提下模拟性能提升。集成测试正是依托这套镜像来验证端到端行为。七、测试依赖与开发配置pypoject.toml 的 pytest 相关配置 值得注意[tool.pytest.ini_options] pythonpath [./src] asyncio_default_fixture_loop_scope function [dependency-groups] dev [ docker7.1.0, pyright1.1.408, pytest-asyncio1.3.0, pytest9.0.2, ruff0.14.13, ]pythonpath [./src]让测试无需安装即可直接导入postgres_mcp包这也是uv run pytest无需额外配置的原因asyncio_default_fixture_loop_scope function为 pytest-asyncio 指定默认的 fixture 事件循环作用域与conftest.py中的事件循环策略配合保证异步测试行为一致dev 依赖组显式声明了 Docker SDK集成测试用、pytest/pytest-asyncio测试框架以及 pyright、ruff静态检查与 lint遵循 pypoject.toml 中的 ruff 规则集 E/F/I/B/W/N/UP/RUF。开发流程可参照仓库 mcp_servers/postgres/README.md 的Postgres MCP Pro Development一节安装uv后执行uv pip install -e . uv sync安装依赖再以uv run postgres-mcp启动服务器。八、调试与排障建议区分是否需要 Docker单元测试tests/unit几乎全部基于 mock可以在无 Docker 环境快速运行集成测试tests/integration、test_explain_plan_real_db.py、test_server_integration.py需要 Docker环境不具备时会被pytest.skip跳过而非失败查看输出时留意 skipped 数量。单测失败定位用文件路径::用例名精确复现配合-v -s查看断言细节连接池与 SQL 驱动相关失败多与 mock 的异步上下文管理器行为有关可对照AsyncContextManagerMock的实现排查。集成测试失败定位tests/utils.py在容器启动失败时会把最近 2000 字符的容器日志打入 pytest 输出是首选的排障线索同时它使用随机容器名postgres-crystal-test-version_随机hex多次运行不会互相干扰。版本差异conftest.py对 Postgres 12/15/16 参数化若只关心某一版本可通过-k关键字过滤例如uv run pytest tests/integration -k postgres-15。版本缓存reset_pg_version_cache在每个测试前重置版本缓存若你新增了依赖 Postgres 版本分支的测试记得保持该 fixture 生效避免缓存污染。九、小结mcp_servers/postgres/tests/README.md虽然篇幅简短却精确勾勒了这套测试体系的使用入口与结构骨架。结合仓库源码可以看到它背后是一套mock 隔离的单元测试 Docker 真实数据库的集成测试双轨体系单元测试覆盖密码脱敏、连接池、SQL 驱动与安全 SQL 校验等核心执行路径集成测试依托内置 HypoPG 的 Postgres 容器验证索引调优与慢查询分析等数据库强相关能力。对开发者而言掌握uv run pytest三种基本用法、理解tests/unit与tests/integration的分层边界再配合conftest.py与tests/utils.py提供的基础设施即可快速上手、调试并扩展这套质量保障体系。【免费下载链接】klavisKlavis AI: MCP integration platforms that let AI agents use tools reliably at any scale项目地址: https://gitcode.com/GitHub_Trending/kl/klavis创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考