用途
ariadne 是一个 MCP(Model Context Protocol)服务器,旨在为 AI 智能体提供识别受影响测试的能力。它由 sazanami 驱动,通过分析代码变更,仅返回需要运行的测试,从而帮助智能体在编辑、验证、提交的内部循环中快速获得反馈。
主要能力
- 受影响测试选择:基于函数级静态分析,找出工作区变更所影响的单元测试。
- MCP 集成:可与 Claude Code、Claude Desktop 及其他 MCP 兼容客户端配合使用。
- 自动 Git Diff:无需手动传递 diff,ariadne 内部执行 git diff。
- 基于 sazanami:使用 Kotlin Analysis API 进行准确的静态分析。
- 工具接口:提供
get_affected_tests工具,接受项目路径、作用域(deep/shallow)和基础分支等参数。 - 明确提示无法分析的情况:当检测到无法分析的变更(构建脚本、资源、未扫描的源集)时,会在工具响应中明确说明,而不是静默报告“无受影响测试”。
使用方式
安装
- Homebrew(推荐):通过 Homebrew 安装后,在 MCP 客户端中注册。
- Docker:挂载要分析的项目,并将
/workspace作为project_path传入。镜像已在官方 MCP Registry 中列出,标识为io.github.MikhailHal/ariadne。 - 手动(发布版 JAR):从 Releases 下载
ariadne-<version>-all.jar(需要 JDK 21+),并在客户端中配置"command": "java", "args": ["-jar", "/path/to/ariadne-<version>-all.jar"]。 - 从源码构建:可自行构建。
配置后使用
AI 智能体可使用 get_affected_tests 工具:
project_path(必填)— Kotlin 项目路径。scope(可选,deep|shallow,默认deep)— 回溯范围:deep— 自base_branch以来的所有变更(已提交和未提交)。最安全,覆盖整个分支,但可能选择更多测试。shallow— 仅未提交的变更(与 HEAD 对比)。最快,适用于紧密的编辑循环。验证已提交的工作由调用方负责。base_branch被忽略。
base_branch(可选,仅 deep 作用域)— 用于比较的分支。省略时,ariadne 使用仓库的默认分支(origin/HEAD)。如果未设置(例如没有远程的仓库),则返回错误要求显式传递base_branch,而不是猜测。
工作流程
- 智能体调用工具 — 将项目路径传递给 ariadne。
- 运行 git diff — ariadne 针对基础分支执行
git diff --unified=0。 - 使用 sazanami 分析 — 构建调用图并查找受影响的测试。
- 返回结果 — 返回测试 FQN(全限定名)列表给智能体。
输出
- 受影响的测试 FQN 列表(已排序)。
- 如果 diff 包含分析范围外的变更(构建脚本、资源、未扫描的源集),会附加说明,建议对这些变更运行完整测试。
- 分析受 120 秒超时限制;超时返回明确错误。
适用场景
- Kotlin/Android 项目的智能体内部循环(编辑、验证、提交),需要快速反馈。
- 在 CI 之前缩小智能体需要运行的测试范围。
- 与 Claude Code、Claude Desktop 等 MCP 客户端集成。
限制
- 速度优先于完整性:静态分析无法追踪所有执行路径,反射、依赖注入框架、数据流间接(如 Flux/MVI 分发)可能隐藏依赖。
- 必须保留 CI 防线:在合并前运行完整测试套件(或保守选择)。ariadne 仅缩小智能体迭代时运行的测试,不能替代 CI。
- 无法分析的情况:构建脚本、资源、未扫描的源集等变更会明确提示。
- 静态分析盲区:如果框架调用你的代码而不是测试调用它,ariadne 无法连接它们。这些是静态分析的局限,不是 bug。
- 模块发现基于约定:解析
settings.gradle(.kts)的 includes,枚举src/<sourceSet>/{kotlin,java}布局,读取project(":x")/ 类型安全访问器依赖。动态 includes、projectDir重映射、自定义srcDirs、由约定插件注入的依赖无法检测。 - 每次请求全量重建图(暂无缓存);分析上限 120 秒。
- 环境要求:JDK 21 或更高版本;Git(用于 diff 检测)。
实际验证
针对 Now in Android(Google 参考 Android 应用 — 34 个模块,约 268 个 Kotlin 文件)进行了测量。已验证的模式包括项目接口后的仓库、库接口覆盖(androidx.datastore.Serializer)、operator fun invoke 用例、@Composable 函数、扩展映射器、ViewModel 属性初始化链和可调用引用。两个代表性结果:
- 更改
core:common的asResult()选择了跨三个模块的 14 个测试,包括仅通过val uiState = ...stateIn(...)可达的 ViewModel 测试。 - 更改映射器
PopulatedNewsResource.asExternalModel()选择了 14 个测试,包括仅通过.map(Type::mapper)链可达的 11 个仓库测试。
测试类选择率:通过更改被测类中的函数并检查该测试类是否被选中,对 Now in Android 中的每个单元测试类进行了测量。Robolectric 不是障碍:这些测试自己调用 composable(setContent { NiaTheme { ... } }),因此调用存在于源码中。决定覆盖率的不是测试运行器,而是测试自身代码是否包含调用。
许可证
完整文本见 LICENSE。