Skip to main content
Glama
zegroged

vacuous-tests-mcp

by zegroged

vacuous-tests-mcp

一个 MCP 服务器,用于找出无论代码做什么都会通过的测试。

空洞测试比缺失测试更糟糕。缺失测试是明显缺失的。空洞测试存在于测试套件中,运行显示绿色,计入总数,并被引用为行为已被覆盖的证据——而实际上它什么也没检查。这是一种无形缺失的覆盖,它恰恰能在测试本应捕获的情况下存活。

它们很容易被无意中写出,也很难通过阅读发现,因为空洞测试和真实测试往往看起来几乎一模一样。

这个案例的构建背景

一个 Rust 文件,共 6,764 行,位于一个测试套件已经定期进行人工审计的项目中。其中有两个测试:

// flagged
const SRC: &str = include_str!("lib.rs");
assert!(SRC.contains("pub sas_verified: bool,"), "the field must be exposed");
// not flagged
const SRC: &str = include_str!("lib.rs");
let prod = SRC.split_once("\n#[cfg(test)]\nmod tests {").expect("test module").0;
assert!(prod.contains("InviterSecrets::create_for_group("), "production never calls it");

两者都嵌入了文件自身的源代码。第一个直接对 SRC 进行断言——而 SRC 包含了测试本身,包括正在搜索的字符串。它通过构造即为真:删除它声称保护的生产代码,它仍然保持绿色。第二个先切掉测试模块,只对生产代码片段进行断言,因此当生产代码发生变化时它会失败。那是一个真正的门禁。

扫描该文件会报告一个发现,位于正确的行,并保留其他四个 include_str! 位置不动。扫描器跟踪绑定而不是对 include_str! 进行模式匹配,这正是区分这两种情况的关键。

Related MCP server: leakguard-mcp

规则

规则

严重级别

捕获内容

self-referential-source

测试嵌入了自身源代码,并断言某个字面量出现在其中。该字面量就在断言中,因此它永远不会失败。

no-assertions

没有任何形式的断言。只有 panic 或抛出异常才能使测试失败,因此错误但安静的行为会通过。

tautological-assertion

assert!(true)assert_eq!(x, x)expect(true).toBe(true)——无论代码如何都成立。

empty-body

函数体中没有可失败的内容。

skipped-test

信息

#[ignore]it.skip@pytest.mark.skip。因为不运行而显示绿色。

语言

语言

方法

准确性

Python

标准库中的 ast

精确

Rust

基于源代码文本的括号匹配扫描器

启发式

JavaScript / TypeScript

基于源代码文本的括号匹配扫描器

启发式

Rust 和 JS 扫描器在匹配之前会屏蔽字符串字面量和注释,因此字符串中的 { 或被注释掉的断言不会误导它们。它们被调优为宁可漏报也不误报:在这里,误报的代价高于漏报,因为第一个错误答案会让人们学会忽略输出。

将每个发现视为需要检查的问题,而不是最终结论。每个发现都指明文件和行号,因此确认只需几秒钟。

安装

尚未发布到 PyPI——从源码安装:

git clone https://github.com/zegroged/vacuous-tests-mcp
cd vacuous-tests-mcp
pip install .

这会将 vacuous-tests-mcp 命令添加到你的 PATH。

从 MCP 客户端使用

在你的客户端的 MCP 配置中添加:

{
  "mcpServers": {
    "vacuous-tests": {
      "command": "vacuous-tests-mcp"
    }
  }
}

对于 Claude Code:

claude mcp add vacuous-tests -- vacuous-tests-mcp

然后要求它扫描某些内容:

扫描 ./src 中无法失败的测试。

工具

scan_tests(path, include_skipped=True, max_findings=100) 遍历文件或目录,并报告无法失败的测试。构建和依赖目录(targetnode_modules.venv 等)会被跳过。发现结果按严重级别从高到低返回,每个结果包含路径、行号、测试名称、规则和代码片段。

list_rules() 每个规则及其描述,以便模型决定要请求什么。

explain_rule(rule) 某个规则检测什么,以及通常如何解决该发现。

服务器只读取。它不写入文件,不执行所扫描的代码,也不会查看给定路径之外的内容。

开发

pip install -e ".[dev]"
pytest

测试套件覆盖了每种语言中的每个规则,更重要的是,检查了位于空洞测试旁边的正常测试不会被报告。还有一个端到端测试,它作为子进程启动服务器,并通过真实的 MCP 握手驱动它,因此协议层得到了覆盖,而不是假设。

限制

  • Rust 和 JS/TS 检测是基于文本的,不是解析。宏生成的测试、不寻常的格式和深度嵌套的闭包可能会被遗漏。

  • no-assertions 不知道测试可能纯粹是为了证明某些东西不会 panic 而存在。这样的测试按规则是真正的阳性,但按意图是误报;使用显式断言说明这一点,它就会安静下来。

  • 只扫描上表中列出的语言。其他文件会被忽略,而不是猜测。

许可证

MIT

Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    A
    quality
    C
    maintenance
    AI-powered code review tool that detects AI-generated code defects invisible to traditional linters — hallucinated packages, deprecated APIs, cross-file contradictions, hidden security anti-patterns, and over-engineering. Works as a standalone CLI, GitHub Action, or MCP server. Supports TypeScript, Python, Java, Go, and Kotlin. Free for individuals, no API key required.
    4
    33

View all related MCP servers

Related MCP Connectors

  • Flaky test detection, root cause analysis, and fix suggestions for development teams.

  • Deterministic validation for AI-generated artifacts: JSON Schema, OpenAPI response, SQL syntax.

  • Zero-config MCP security scanner for AI-generated apps. 25K+ vulnerability patterns.

View all MCP Connectors

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/zegroged/vacuous-tests-mcp'

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